home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / SoftwareProperties / SoftwareProperties.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  30.2 KB  |  949 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import sys
  5. import apt
  6. import apt_pkg
  7. import gobject
  8. import shutil
  9. import gettext
  10. import tempfile
  11. from gettext import gettext as _
  12. import os
  13. import string
  14. import re
  15. from UpdateManager.Common.SimpleGladeApp import SimpleGladeApp
  16. from UpdateManager.Common.HelpViewer import HelpViewer
  17. import UpdateManager.Common.aptsources as aptsources
  18. import dialog_add
  19. import dialog_edit
  20. import dialog_cache_outdated
  21. import dialog_add_sources_list
  22. from dialog_apt_key import apt_key
  23. from utils import *
  24. (LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3)
  25. CONF_MAP = {
  26.     'autoupdate': 'APT::Periodic::Update-Package-Lists',
  27.     'autodownload': 'APT::Periodic::Download-Upgradeable-Packages',
  28.     'autoclean': 'APT::Periodic::AutocleanInterval',
  29.     'unattended': 'APT::Periodic::Unattended-Upgrade',
  30.     'max_size': 'APT::Archives::MaxSize',
  31.     'max_age': 'APT::Archives::MaxAge' }
  32. (COLUMN_ACTIVE, COLUMN_DESC) = range(2)
  33. RESPONSE_REPLACE = 1
  34. RESPONSE_ADD = 2
  35. (STORE_ACTIVE, STORE_DESCRIPTION, STORE_SOURCE, STORE_SEPARATOR, STORE_VISIBLE) = range(5)
  36.  
  37. class SoftwareProperties(SimpleGladeApp):
  38.     
  39.     def __init__(self, datadir = None, options = None, parent = None, file = None):
  40.         gtk.window_set_default_icon_name('software-properties')
  41.         if datadir == None:
  42.             datadir = '/usr/share/update-manager/'
  43.         
  44.         self.datadir = datadir
  45.         SimpleGladeApp.__init__(self, datadir + 'glade/SoftwareProperties.glade', None, domain = 'update-manager')
  46.         self.modified = False
  47.         self.file = file
  48.         self.distro = aptsources.Distribution()
  49.         cell = gtk.CellRendererText()
  50.         self.combobox_server.pack_start(cell, True)
  51.         self.combobox_server.add_attribute(cell, 'text', 0)
  52.         self.handler_server_changed = self.combobox_server.connect('changed', self.on_combobox_server_changed)
  53.         self.handler_source_code_changed = self.checkbutton_source_code.connect('toggled', self.on_checkbutton_source_code_toggled)
  54.         if parent:
  55.             self.window_main.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
  56.             self.window_main.show()
  57.             self.window_main.set_transient_for(parent)
  58.         
  59.         self.options = options
  60.         if options and options.toplevel != None:
  61.             self.window_main.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
  62.             self.window_main.show()
  63.             toplevel = gtk.gdk.window_foreign_new(int(options.toplevel))
  64.             self.window_main.window.set_transient_for(toplevel)
  65.         
  66.         self.init_sourceslist()
  67.         self.reload_sourceslist()
  68.         self.backup_sourceslist()
  69.         self.window_main.show()
  70.         self.combobox_interval_mapping = {
  71.             0: 1,
  72.             1: 2,
  73.             2: 7,
  74.             3: 14 }
  75.         self.combobox_update_interval.set_active(0)
  76.         update_days = apt_pkg.Config.FindI(CONF_MAP['autoupdate'])
  77.         self.combobox_update_interval.append_text(_('Daily'))
  78.         self.combobox_update_interval.append_text(_('Every two days'))
  79.         self.combobox_update_interval.append_text(_('Weekly'))
  80.         self.combobox_update_interval.append_text(_('Every two weeks'))
  81.         if update_days not in self.combobox_interval_mapping.values():
  82.             if update_days > 0:
  83.                 self.combobox_update_interval.append_text(_('Every %s days') % update_days)
  84.                 self.combobox_interval_mapping[4] = update_days
  85.             
  86.         
  87.         for key in self.combobox_interval_mapping:
  88.             if self.combobox_interval_mapping[key] == update_days:
  89.                 self.combobox_update_interval.set_active(key)
  90.                 break
  91.                 continue
  92.         
  93.         if update_days >= 1:
  94.             self.checkbutton_auto_update.set_active(True)
  95.             self.combobox_update_interval.set_sensitive(True)
  96.         else:
  97.             self.checkbutton_auto_update.set_active(False)
  98.             self.combobox_update_interval.set_sensitive(False)
  99.         self.combobox_delete_interval_mapping = {
  100.             0: 7,
  101.             1: 14,
  102.             2: 30 }
  103.         delete_days = apt_pkg.Config.FindI(CONF_MAP['max_age'])
  104.         self.combobox_delete_interval.append_text(_('After one week'))
  105.         self.combobox_delete_interval.append_text(_('After two weeks'))
  106.         self.combobox_delete_interval.append_text(_('After one month'))
  107.         if delete_days not in self.combobox_delete_interval_mapping.values():
  108.             if delete_days > 0 and CONF_MAP['autoclean'] != 0:
  109.                 self.combobox_delete_interval.append_text(_('After %s days') % delete_days)
  110.                 self.combobox_delete_interval_mapping[3] = delete_days
  111.             
  112.         
  113.         for key in self.combobox_delete_interval_mapping:
  114.             if self.combobox_delete_interval_mapping[key] == delete_days:
  115.                 self.combobox_delete_interval.set_active(key)
  116.                 break
  117.                 continue
  118.         
  119.         if delete_days >= 1 and apt_pkg.Config.FindI(CONF_MAP['autoclean']) != 0:
  120.             self.checkbutton_auto_delete.set_active(True)
  121.             self.combobox_delete_interval.set_sensitive(True)
  122.         else:
  123.             self.checkbutton_auto_delete.set_active(False)
  124.             self.combobox_delete_interval.set_sensitive(False)
  125.         if apt_pkg.Config.FindI(CONF_MAP['autodownload']) == 1:
  126.             self.checkbutton_auto_download.set_active(True)
  127.         else:
  128.             self.checkbutton_auto_download.set_active(False)
  129.         if os.path.exists('/usr/bin/unattended-upgrade'):
  130.             self.checkbutton_unattended.show()
  131.         else:
  132.             self.checkbutton_unattended.hide()
  133.         if apt_pkg.Config.FindI(CONF_MAP['unattended']) == 1:
  134.             self.checkbutton_unattended.set_active(True)
  135.         else:
  136.             self.checkbutton_unattended.set_active(False)
  137.         self.help_viewer = HelpViewer('update-manager#setting-preferences')
  138.         if self.help_viewer.check() == False:
  139.             self.button_help.set_sensitive(False)
  140.         
  141.         self.apt_key = apt_key()
  142.         self.init_keyslist()
  143.         self.reload_keyslist()
  144.         self.treeview_sources.drag_dest_set(gtk.DEST_DEFAULT_ALL, [
  145.             ('text/uri-list', 0, 0)], gtk.gdk.ACTION_COPY)
  146.         self.treeview_sources.connect('drag_data_received', self.on_sources_drag_data_received)
  147.         if self.file != None:
  148.             self.open_file(file)
  149.         
  150.  
  151.     
  152.     def distro_to_widgets(self):
  153.         '''
  154.     Represent the distro information in the user interface
  155.     '''
  156.         self.label_updates.set_label('<b>%s</b>' % _('%s updates') % self.distro.id)
  157.         self.label_dist_name.set_label('%s' % self.distro.description)
  158.         for checkbutton in self.vbox_dist_comps.get_children():
  159.             self.vbox_dist_comps.remove(checkbutton)
  160.         
  161.         for comp in self.distro.source_template.components.keys():
  162.             checkbox = gtk.CheckButton(label = self.distro.source_template.components[comp][2])
  163.             if comp in self.distro.download_comps:
  164.                 checkbox.set_active(True)
  165.             
  166.             checkbox.connect('toggled', self.on_component_toggled, comp)
  167.             self.vbox_dist_comps.add(checkbox)
  168.             checkbox.show()
  169.         
  170.         for checkbutton in self.vbox_updates.get_children():
  171.             self.vbox_updates.remove(checkbutton)
  172.         
  173.         for template in self.distro.source_template.children:
  174.             checkbox = gtk.CheckButton(label = template.description)
  175.             comps = []
  176.             for child in self.distro.child_sources:
  177.                 if child.template == template:
  178.                     comps.extend(child.comps)
  179.                     continue
  180.             
  181.             if len(comps) > 0 and len(self.distro.enabled_comps ^ set(comps)) == 0:
  182.                 checkbox.set_active(True)
  183.             elif len(comps) > 0 and len(self.distro.enabled_comps ^ set(comps)) != 0:
  184.                 checkbox.set_active(False)
  185.                 checkbox.set_inconsistent(True)
  186.             else:
  187.                 checkbox.set_active(False)
  188.             checkbox.connect('toggled', self.on_checkbutton_child_toggled, template)
  189.             self.vbox_updates.add(checkbox)
  190.             checkbox.show()
  191.         
  192.         if len(self.distro.enabled_comps) < 1:
  193.             self.vbox_updates.set_sensitive(False)
  194.         else:
  195.             self.vbox_updates.set_sensitive(True)
  196.         self.combobox_server.handler_block(self.handler_server_changed)
  197.         server_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
  198.         self.combobox_server.set_model(server_store)
  199.         server_store.append([
  200.             _('Main server'),
  201.             self.distro.main_server])
  202.         if self.distro.country != None:
  203.             server_store.append([
  204.                 _('Server for %s') % gettext.dgettext('iso-3166', self.distro.country).rstrip(),
  205.                 self.distro.nearest_server])
  206.         else:
  207.             server_store.append([
  208.                 _('Nearest server'),
  209.                 self.distro.nearest_server])
  210.         if len(self.distro.used_servers) > 0:
  211.             for server in self.distro.used_servers:
  212.                 if not re.match(server, self.distro.main_server) and not re.match(server, self.distro.nearest_server):
  213.                     country = ''
  214.                     i = server.find('://')
  215.                     l = server.find('.archive.ubuntu.com')
  216.                     if i != -1 and l != -1:
  217.                         country = server[i + len('://'):l]
  218.                     
  219.                     if self.distro.countries.has_key(country):
  220.                         server_store.append([
  221.                             _('Server for %s') % gettext.dgettext('iso-3166', self.distro.countries[country].rstrip()),
  222.                             server])
  223.                     else:
  224.                         server_store.append([
  225.                             '%s' % server,
  226.                             server])
  227.                 self.distro.countries.has_key(country)
  228.             
  229.             if len(self.distro.used_servers) > 1:
  230.                 server_store.append([
  231.                     _('Custom servers'),
  232.                     None])
  233.                 self.combobox_server.set_active(2)
  234.             elif self.distro.used_servers[0] == self.distro.main_server:
  235.                 self.combobox_server.set_active(0)
  236.             elif self.distro.used_servers[0] == self.distro.nearest_server:
  237.                 self.combobox_server.set_active(1)
  238.             elif len(self.distro.used_servers) == 1:
  239.                 self.combobox_server.set_active(2)
  240.             
  241.         else:
  242.             self.combobox_server.set_active(0)
  243.         self.combobox_server.handler_unblock(self.handler_server_changed)
  244.         self.checkbutton_source_code.handler_block(self.handler_source_code_changed)
  245.         self.checkbutton_source_code.set_inconsistent(False)
  246.         if len(self.distro.source_code_sources) < 1:
  247.             self.checkbutton_source_code.set_active(False)
  248.             self.distro.get_source_code = False
  249.         else:
  250.             self.checkbutton_source_code.set_active(True)
  251.             self.distro.get_source_code = True
  252.             templates = { }
  253.             sources = []
  254.             sources.extend(self.distro.main_sources)
  255.             sources.extend(self.distro.child_sources)
  256.             for source in sources:
  257.                 if templates.has_key(source.template):
  258.                     for comp in source.comps:
  259.                         templates[source.template].add(comp)
  260.                     
  261.                 templates[source.template] = set(source.comps)
  262.             
  263.             if len(self.distro.cdrom_sources) > 0:
  264.                 templates[self.distro.source_template] = self.distro.cdrom_comps
  265.             
  266.             for source in self.distro.source_code_sources:
  267.                 if not templates.has_key(source.template) or templates.has_key(source.template):
  268.                     if not len(set(templates[source.template]) ^ set(source.comps)) == 0:
  269.                         pass
  270.                     if not (len(set(source.comps) ^ self.distro.enabled_comps) == 0):
  271.                         self.checkbutton_source_code.set_inconsistent(True)
  272.                         self.distro.get_source_code = False
  273.                         break
  274.                         continue
  275.             
  276.         self.checkbutton_source_code.handler_unblock(self.handler_source_code_changed)
  277.         if len(self.cdrom_store) == 0:
  278.             self.treeview_cdroms.set_sensitive(False)
  279.         else:
  280.             self.treeview_cdroms.set_sensitive(True)
  281.  
  282.     
  283.     def on_combobox_server_changed(self, combobox):
  284.         '''
  285.     Replace the servers used by the main and update sources with
  286.     the selected one
  287.     '''
  288.         server_store = combobox.get_model()
  289.         iter = combobox.get_active_iter()
  290.         uri_selected = server_store.get_value(iter, 1)
  291.         sources = []
  292.         sources.extend(self.distro.main_sources)
  293.         sources.extend(self.distro.child_sources)
  294.         sources.extend(self.distro.source_code_sources)
  295.         for source in sources:
  296.             if 'security.ubuntu.com' not in source.uri:
  297.                 source.uri = uri_selected
  298.                 continue
  299.         
  300.         self.distro.ddefault_server = uri_selected
  301.         self.modified_sourceslist()
  302.  
  303.     
  304.     def on_component_toggled(self, checkbutton, comp):
  305.         '''
  306.     Sync the components of all main sources (excluding cdroms),
  307.     child sources and source code sources
  308.     '''
  309.         if checkbutton.get_active() == True:
  310.             self.distro.enable_component(self.sourceslist, comp)
  311.         else:
  312.             self.distro.disable_component(self.sourceslist, comp)
  313.         self.modified_sourceslist()
  314.  
  315.     
  316.     def massive_debug_output(self):
  317.         '''
  318.       do not write our changes yet - just print them to std_out
  319.       '''
  320.         print 'START SOURCES.LIST:'
  321.         for source in self.sourceslist:
  322.             print source.str()
  323.         
  324.         print 'END SOURCES.LIST\n'
  325.  
  326.     
  327.     def on_checkbutton_child_toggled(self, checkbutton, template):
  328.         '''
  329.     Enable or disable a child repo of the distribution main repository
  330.     '''
  331.         if checkbutton.get_active() == False:
  332.             for source in self.distro.child_sources:
  333.                 if source.template == template:
  334.                     self.sourceslist.remove(source)
  335.                     continue
  336.             
  337.         else:
  338.             self.distro.add_source(self.sourceslist, uri = template.base_uri, dist = template.name)
  339.         self.modified_sourceslist()
  340.  
  341.     
  342.     def on_checkbutton_source_code_toggled(self, checkbutton):
  343.         '''
  344.     Disable or enable the source code for all sources
  345.     '''
  346.         self.distro.get_source_code = checkbutton.get_active()
  347.         sources = []
  348.         sources.extend(self.distro.main_sources)
  349.         sources.extend(self.distro.child_sources)
  350.         for source in self.distro.source_code_sources:
  351.             self.sourceslist.remove(source)
  352.         
  353.         if checkbutton.get_active() == True:
  354.             for source in sources:
  355.                 self.sourceslist.add('deb-src', source.uri, source.dist, source.comps, 'Added by software-properties', self.sourceslist.list.index(source) + 1, source.file)
  356.             
  357.             for source in self.distro.cdrom_sources:
  358.                 self.sourceslist.add('deb-src', self.distro.source_template.base_uri, self.distro.source_template.name, source.comps, 'Added by software-properties', self.sourceslist.list.index(source) + 1, source.file)
  359.             
  360.         
  361.         self.modified_sourceslist()
  362.  
  363.     
  364.     def on_checkbutton_popcon_toggled(self, widget):
  365.         ''' The user clicked on the popcon paritipcation button '''
  366.         popcon = '/etc/popularity-contest.conf'
  367.         if widget.get_active():
  368.             new_value = 'yes'
  369.         else:
  370.             new_value = 'no'
  371.         if os.path.exists(popcon):
  372.             lines = open(popcon).read().split('\n')
  373.             for line in lines:
  374.                 
  375.                 try:
  376.                     (key, value) = line.split('=')
  377.                     if key == 'PARTICIPATE':
  378.                         lines[lines.index(line)] = 'PARTICIPATE="%s"' % new_value
  379.                 continue
  380.                 except ValueError:
  381.                     continue
  382.                     continue
  383.                 
  384.  
  385.             
  386.             open(popcon, 'w').write('\n'.join(lines))
  387.         
  388.  
  389.     
  390.     def open_file(self, file):
  391.         '''Show an confirmation for adding the channels of the specified file'''
  392.         dialog = dialog_add_sources_list.AddSourcesList(self.window_main, self.sourceslist, self.render_source, self.get_comparable, self.datadir, file)
  393.         (res, new_sources) = dialog.run()
  394.         if res == RESPONSE_REPLACE:
  395.             self.sourceslist.list = []
  396.         
  397.         if res in (RESPONSE_ADD, RESPONSE_REPLACE):
  398.             for source in new_sources:
  399.                 self.sourceslist.add(source.type, source.uri, source.dist, source.comps, source.comment)
  400.             
  401.             self.modified_sourceslist()
  402.         
  403.  
  404.     
  405.     def on_sources_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp):
  406.         '''Extract the dropped file pathes and open the first file, only'''
  407.         uri = selection.data.strip()
  408.         uri_splitted = uri.split()
  409.         if len(uri_splitted) > 0:
  410.             self.open_file(uri_splitted[0])
  411.         
  412.  
  413.     
  414.     def hide(self):
  415.         self.window_main.hide()
  416.  
  417.     
  418.     def init_sourceslist(self):
  419.         '''
  420.     Read all valid sources into our ListStore
  421.     '''
  422.         self.cdrom_store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN)
  423.         self.treeview_cdroms.set_model(self.cdrom_store)
  424.         self.source_store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN)
  425.         self.treeview_sources.set_model(self.source_store)
  426.         self.treeview_sources.set_row_separator_func(self.is_separator, STORE_SEPARATOR)
  427.         cell_desc = gtk.CellRendererText()
  428.         cell_desc.set_property('xpad', 2)
  429.         cell_desc.set_property('ypad', 2)
  430.         col_desc = gtk.TreeViewColumn(_('Software Channel'), cell_desc, markup = COLUMN_DESC)
  431.         col_desc.set_max_width(1000)
  432.         cell_toggle = gtk.CellRendererToggle()
  433.         cell_toggle.set_property('xpad', 2)
  434.         cell_toggle.set_property('ypad', 2)
  435.         cell_toggle.connect('toggled', self.on_channel_toggled, self.cdrom_store)
  436.         col_active = gtk.TreeViewColumn(_('Active'), cell_toggle, active = COLUMN_ACTIVE)
  437.         self.treeview_cdroms.append_column(col_active)
  438.         self.treeview_cdroms.append_column(col_desc)
  439.         cell_desc = gtk.CellRendererText()
  440.         cell_desc.set_property('xpad', 2)
  441.         cell_desc.set_property('ypad', 2)
  442.         col_desc = gtk.TreeViewColumn(_('Software Channel'), cell_desc, markup = COLUMN_DESC)
  443.         col_desc.set_max_width(1000)
  444.         cell_toggle = gtk.CellRendererToggle()
  445.         cell_toggle.set_property('xpad', 2)
  446.         cell_toggle.set_property('ypad', 2)
  447.         cell_toggle.connect('toggled', self.on_channel_toggled, self.source_store)
  448.         col_active = gtk.TreeViewColumn(_('Active'), cell_toggle, active = COLUMN_ACTIVE)
  449.         self.treeview_sources.append_column(col_active)
  450.         self.treeview_sources.append_column(col_desc)
  451.         self.sourceslist = aptsources.SourcesList()
  452.  
  453.     
  454.     def backup_sourceslist(self):
  455.         '''
  456.     Duplicate the list of sources
  457.     '''
  458.         self.sourceslist_backup = []
  459.         for source in self.sourceslist.list:
  460.             source_bkp = aptsources.SourceEntry(line = source.line, file = source.file)
  461.             self.sourceslist_backup.append(source_bkp)
  462.         
  463.  
  464.     
  465.     def on_channel_activate(self, treeview, path, column):
  466.         '''Open the edit dialog if a channel was double clicked'''
  467.         self.on_edit_clicked(treeview)
  468.  
  469.     
  470.     def on_treeview_sources_cursor_changed(self, treeview):
  471.         '''Enable the buttons remove and edit if a channel is selected'''
  472.         sel = self.treeview_sources.get_selection()
  473.         (model, iter) = sel.get_selected()
  474.         if iter:
  475.             self.button_edit.set_sensitive(True)
  476.             self.button_remove.set_sensitive(True)
  477.         else:
  478.             self.button_edit.set_sensitive(False)
  479.             self.button_remove.set_sensitive(False)
  480.  
  481.     
  482.     def on_channel_toggled(self, cell_toggle, path, store):
  483.         '''Enable or disable the selected channel'''
  484.         iter = store.get_iter((int(path),))
  485.         source_entry = store.get_value(iter, STORE_SOURCE)
  486.         source_entry.disabled = not (source_entry.disabled)
  487.         store.set_value(iter, STORE_ACTIVE, not (source_entry.disabled))
  488.         self.modified_sourceslist()
  489.  
  490.     
  491.     def init_keyslist(self):
  492.         self.keys_store = gtk.ListStore(str)
  493.         self.treeview2.set_model(self.keys_store)
  494.         tr = gtk.CellRendererText()
  495.         keys_col = gtk.TreeViewColumn('Key', tr, text = 0)
  496.         self.treeview2.append_column(keys_col)
  497.  
  498.     
  499.     def on_button_revert_clicked(self, button):
  500.         '''Restore the source list from the startup of the dialog'''
  501.         self.sourceslist.list = []
  502.         for source in self.sourceslist_backup:
  503.             source_reset = aptsources.SourceEntry(line = source.line, file = source.file)
  504.             self.sourceslist.list.append(source_reset)
  505.         
  506.         self.save_sourceslist()
  507.         self.reload_sourceslist()
  508.         self.button_revert.set_sensitive(False)
  509.         self.modified = False
  510.  
  511.     
  512.     def modified_sourceslist(self):
  513.         '''The sources list was changed and now needs to be saved and reloaded'''
  514.         self.massive_debug_output()
  515.         self.modified = True
  516.         self.button_revert.set_sensitive(True)
  517.         self.save_sourceslist()
  518.         self.reload_sourceslist()
  519.  
  520.     
  521.     def render_source(self, source):
  522.         '''Render a nice output to show the source in a treeview'''
  523.         if source.template == None:
  524.             if source.comment:
  525.                 contents = '<b>%s</b>' % source.comment
  526.                 if len(source.comps) > 1:
  527.                     for c in source.comps:
  528.                         contents += ' %s' % c
  529.                     
  530.                 
  531.             else:
  532.                 contents = '<b>%s %s</b>' % (source.uri, source.dist)
  533.                 for c in source.comps:
  534.                     contents += ' %s' % c
  535.                 
  536.             if source.type in ('deb-src', 'rpm-src'):
  537.                 contents += ' %s' % _('(Source Code)')
  538.             
  539.             return contents
  540.         else:
  541.             contents = '<b>%s</b>' % source.template.description
  542.             if source.type in ('deb-src', 'rpm-src'):
  543.                 contents += ' (%s)' % _('Source Code')
  544.             
  545.             if source.comment:
  546.                 contents += ' %s' % source.comment
  547.             
  548.             if source.template.child == False:
  549.                 for comp in source.comps:
  550.                     if source.template.components.has_key(comp):
  551.                         print source.template.components[comp]
  552.                         (desc, enabled, desc_long) = source.template.components[comp]
  553.                         contents += '\n%s' % desc
  554.                         continue
  555.                     contents += '\n%s' % comp
  556.                 
  557.             
  558.             return contents
  559.  
  560.     
  561.     def get_comparable(self, source):
  562.         '''extract attributes to sort the sources'''
  563.         cur_sys = 1
  564.         has_template = 1
  565.         has_comment = 1
  566.         is_source = 1
  567.         revert_numbers = string.maketrans('0123456789', '9876543210')
  568.         if source.template:
  569.             has_template = 0
  570.             desc = source.template.description
  571.             if source.template.distribution == self.distro:
  572.                 cur_sys = 0
  573.             
  574.         else:
  575.             desc = '%s %s %s' % (source.uri, source.dist, source.comps)
  576.             if source.comment:
  577.                 has_comment = 0
  578.             
  579.         if source.type.find('src'):
  580.             is_source = 0
  581.         
  582.         return (cur_sys, has_template, has_comment, is_source, desc.translate(revert_numbers))
  583.  
  584.     
  585.     def reload_sourceslist(self):
  586.         (path_x, path_y) = self.treeview_sources.get_cursor()
  587.         self.source_store.clear()
  588.         self.cdrom_store.clear()
  589.         self.sourceslist.refresh()
  590.         self.sourceslist_visible = []
  591.         self.distro.get_sources(self.sourceslist)
  592.         for source in self.sourceslist.list:
  593.             if not (source.invalid):
  594.                 if (source not in self.distro.main_sources and source not in self.distro.cdrom_sources and source not in self.distro.child_sources or source not in self.distro.disabled_sources) and source not in self.distro.source_code_sources:
  595.                     self.sourceslist_visible.append(source)
  596.                     continue
  597.             if not (source.invalid) and source in self.distro.cdrom_sources:
  598.                 contents = self.render_source(source)
  599.                 self.cdrom_store.append([
  600.                     not (source.disabled),
  601.                     contents,
  602.                     source,
  603.                     False,
  604.                     True])
  605.                 continue
  606.         
  607.         self.sourceslist_visible.sort(key = self.get_comparable)
  608.         for source in self.sourceslist_visible:
  609.             contents = self.render_source(source)
  610.             self.source_store.append([
  611.                 not (source.disabled),
  612.                 contents,
  613.                 source,
  614.                 False,
  615.                 True])
  616.         
  617.         (path_x, path_y) = self.treeview_sources.get_cursor()
  618.         if len(self.source_store) < 1 or path_x < 0:
  619.             self.button_remove.set_sensitive(False)
  620.             self.button_edit.set_sensitive(False)
  621.         
  622.         self.distro.get_sources(self.sourceslist)
  623.         self.distro_to_widgets()
  624.  
  625.     
  626.     def is_separator(self, model, iter, column):
  627.         return model.get_value(iter, column)
  628.  
  629.     
  630.     def reload_keyslist(self):
  631.         self.keys_store.clear()
  632.         for key in self.apt_key.list():
  633.             self.keys_store.append([
  634.                 key])
  635.         
  636.  
  637.     
  638.     def on_combobox_update_interval_changed(self, widget):
  639.         i = self.combobox_update_interval.get_active()
  640.         if i != -1:
  641.             value = self.combobox_interval_mapping[i]
  642.             if not value == apt_pkg.Config.FindI(CONF_MAP['autoupdate']):
  643.                 apt_pkg.Config.Set(CONF_MAP['autoupdate'], str(value))
  644.                 self.write_config()
  645.             
  646.         
  647.  
  648.     
  649.     def on_opt_autoupdate_toggled(self, widget):
  650.         if self.checkbutton_auto_update.get_active():
  651.             self.combobox_update_interval.set_sensitive(True)
  652.             i = self.combobox_update_interval.get_active()
  653.             if i == -1:
  654.                 i = 0
  655.                 self.combobox_update_interval.set_active(i)
  656.             
  657.             value = self.combobox_interval_mapping[i]
  658.         else:
  659.             self.combobox_update_interval.set_sensitive(False)
  660.             value = 0
  661.         apt_pkg.Config.Set(CONF_MAP['autoupdate'], str(value))
  662.         self.write_config()
  663.  
  664.     
  665.     def on_opt_unattended_toggled(self, widget):
  666.         if self.checkbutton_unattended.get_active():
  667.             self.checkbutton_unattended.set_active(True)
  668.             apt_pkg.Config.Set(CONF_MAP['unattended'], str(1))
  669.         else:
  670.             self.checkbutton_unattended.set_active(False)
  671.             apt_pkg.Config.Set(CONF_MAP['unattended'], str(0))
  672.         self.write_config()
  673.  
  674.     
  675.     def on_opt_autodownload_toggled(self, widget):
  676.         if self.checkbutton_auto_download.get_active():
  677.             self.checkbutton_auto_download.set_active(True)
  678.             apt_pkg.Config.Set(CONF_MAP['autodownload'], str(1))
  679.         else:
  680.             self.checkbutton_auto_download.set_active(False)
  681.             apt_pkg.Config.Set(CONF_MAP['autodownload'], str(0))
  682.         self.write_config()
  683.  
  684.     
  685.     def on_combobox_delete_interval_changed(self, widget):
  686.         i = self.combobox_delete_interval.get_active()
  687.         if i != -1:
  688.             value = self.combobox_delete_interval_mapping[i]
  689.             if not value == apt_pkg.Config.FindI(CONF_MAP['max_age']):
  690.                 apt_pkg.Config.Set(CONF_MAP['max_age'], str(value))
  691.                 self.write_config()
  692.             
  693.         
  694.  
  695.     
  696.     def on_opt_autodelete_toggled(self, widget):
  697.         if self.checkbutton_auto_delete.get_active():
  698.             self.combobox_delete_interval.set_sensitive(True)
  699.             i = self.combobox_delete_interval.get_active()
  700.             if i == -1:
  701.                 i = 0
  702.                 self.combobox_delete_interval.set_active(i)
  703.             
  704.             value_maxage = self.combobox_delete_interval_mapping[i]
  705.             value_clean = 1
  706.             apt_pkg.Config.Set(CONF_MAP['max_age'], str(value_maxage))
  707.         else:
  708.             self.combobox_delete_interval.set_sensitive(False)
  709.             value_clean = 0
  710.         apt_pkg.Config.Set(CONF_MAP['autoclean'], str(value_clean))
  711.         self.write_config()
  712.  
  713.     
  714.     def write_config(self):
  715.         conffiles = [
  716.             '/etc/apt/apt.conf.d/10periodic',
  717.             '/etc/apt/apt.conf.d/15adept-periodic-update']
  718.         for f in conffiles:
  719.             if os.path.isfile(f):
  720.                 break
  721.                 continue
  722.         else:
  723.             print 'No config found, creating one'
  724.         for periodic in conffiles:
  725.             content = []
  726.             if os.path.isfile(periodic):
  727.                 content = open(periodic, 'r').readlines()
  728.                 cnf = apt_pkg.Config.SubTree('APT::Periodic')
  729.                 f = open(periodic, 'w')
  730.                 for line in content:
  731.                     for key in cnf.List():
  732.                         if line.find('APT::Periodic::%s' % key) >= 0:
  733.                             break
  734.                             continue
  735.                     
  736.                 
  737.                 for i in cnf.List():
  738.                     f.write('APT::Periodic::%s "%s";\n' % (i, cnf.FindI(i)))
  739.                 
  740.                 f.close()
  741.                 continue
  742.         
  743.  
  744.     
  745.     def save_sourceslist(self):
  746.         self.sourceslist.backup('.save')
  747.         self.sourceslist.save()
  748.  
  749.     
  750.     def on_add_clicked(self, widget):
  751.         dialog = dialog_add.dialog_add(self.window_main, self.sourceslist, self.datadir)
  752.         line = dialog.run()
  753.         if line != None:
  754.             self.sourceslist.list.append(aptsources.SourceEntry(line))
  755.             self.modified_sourceslist()
  756.         
  757.  
  758.     
  759.     def on_edit_clicked(self, widget):
  760.         sel = self.treeview_sources.get_selection()
  761.         (model, iter) = sel.get_selected()
  762.         if not iter:
  763.             return None
  764.         
  765.         source_entry = model.get_value(iter, LIST_ENTRY_OBJ)
  766.         dialog = dialog_edit.dialog_edit(self.window_main, self.sourceslist, source_entry, self.datadir)
  767.         if dialog.run() == gtk.RESPONSE_OK:
  768.             self.modified_sourceslist()
  769.         
  770.  
  771.     
  772.     def on_channel_activated(self, treeview, path, column):
  773.         '''Open the edit dialog if a channel was double clicked'''
  774.         if self.button_edit.get_property('sensitive') == True:
  775.             self.on_edit_clicked(treeview)
  776.         
  777.  
  778.     
  779.     def on_treeview_sources_cursor_changed(self, treeview):
  780.         '''set the sensitiveness of the edit and remove button
  781.        corresponding to the selected channel'''
  782.         sel = self.treeview_sources.get_selection()
  783.         (model, iter) = sel.get_selected()
  784.         if not iter:
  785.             self.button_edit.set_sensitive(False)
  786.             self.button_remove.set_sensitive(False)
  787.             return None
  788.         
  789.         self.button_remove.set_sensitive(True)
  790.         source_entry = model.get_value(iter, LIST_ENTRY_OBJ)
  791.         if source_entry.uri.startswith('cdrom:'):
  792.             self.button_edit.set_sensitive(False)
  793.         else:
  794.             self.button_edit.set_sensitive(True)
  795.  
  796.     
  797.     def on_remove_clicked(self, widget):
  798.         model = self.treeview_sources.get_model()
  799.         (path, column) = self.treeview_sources.get_cursor()
  800.         iter = model.get_iter(path)
  801.         if iter:
  802.             source = model.get_value(iter, LIST_ENTRY_OBJ)
  803.             self.sourceslist.remove(source)
  804.             self.modified_sourceslist()
  805.         
  806.  
  807.     
  808.     def add_key_clicked(self, widget):
  809.         chooser = gtk.FileChooserDialog(title = _('Import key'), parent = self.window_main, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
  810.         res = chooser.run()
  811.         chooser.hide()
  812.         if res == gtk.RESPONSE_ACCEPT:
  813.             if not self.apt_key.add(chooser.get_filename()):
  814.                 error(self.window_main, _('Error importing selected file'), _('The selected file may not be a GPG key file or it might be corrupt.'))
  815.             
  816.             self.reload_keyslist()
  817.         
  818.  
  819.     
  820.     def remove_key_clicked(self, widget):
  821.         selection = self.treeview2.get_selection()
  822.         (model, a_iter) = selection.get_selected()
  823.         if a_iter == None:
  824.             return None
  825.         
  826.         key = model.get_value(a_iter, 0)
  827.         if not self.apt_key.rm(key[:8]):
  828.             error(self.main, _('Error removing the key'), _('The key you selected could not be removed. Please report this as a bug.'))
  829.         
  830.         self.reload_keyslist()
  831.  
  832.     
  833.     def on_restore_clicked(self, widget):
  834.         self.apt_key.update()
  835.         self.reload_keyslist()
  836.  
  837.     
  838.     def on_delete_event(self, widget, args):
  839.         self.on_close_button(widget)
  840.  
  841.     
  842.     def on_close_button(self, widget):
  843.         if self.modified == True and self.options.toplevel == None:
  844.             d = dialog_cache_outdated.DialogCacheOutdated(self.window_main, self.datadir)
  845.             res = d.run()
  846.         
  847.         self.quit()
  848.  
  849.     
  850.     def on_help_button(self, widget):
  851.         self.help_viewer.run()
  852.  
  853.     
  854.     def on_button_add_cdrom_clicked(self, widget):
  855.         saved_entry = apt_pkg.Config.Find('Dir::Etc::sourcelist')
  856.         tmp = tempfile.NamedTemporaryFile()
  857.         apt_pkg.Config.Set('Dir::Etc::sourcelist', tmp.name)
  858.         progress = GtkCdromProgress(self.datadir, self.window_main)
  859.         cdrom = apt_pkg.GetCdrom()
  860.         
  861.         try:
  862.             res = cdrom.Add(progress)
  863.         except SystemError:
  864.             msg = None
  865.             progress.close()
  866.             dialog = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_OK, message_format = None)
  867.             dialog.set_markup(_('<big><b>Error scaning the CD</b></big>\n\n%s' % msg))
  868.             res = dialog.run()
  869.             dialog.destroy()
  870.             return None
  871.  
  872.         apt_pkg.Config.Set('Dir::Etc::sourcelist', saved_entry)
  873.         if res == False:
  874.             progress.close()
  875.             return None
  876.         
  877.         line = ''
  878.         for x in open(tmp.name):
  879.             line = x
  880.         
  881.         if line != '':
  882.             full_path = '%s%s' % (apt_pkg.Config.FindDir('Dir::Etc'), saved_entry)
  883.             self.sourceslist.list.append(aptsources.SourceEntry(line, full_path))
  884.             self.reload_sourceslist()
  885.             self.modified = True
  886.         
  887.  
  888.  
  889.  
  890. class GtkCdromProgress(apt.progress.CdromProgress, SimpleGladeApp):
  891.     
  892.     def __init__(self, datadir, parent):
  893.         SimpleGladeApp.__init__(self, datadir + 'glade/SoftwarePropertiesDialogs.glade', 'dialog_cdrom_progress', domain = 'update-manager')
  894.         self.dialog_cdrom_progress.show()
  895.         self.dialog_cdrom_progress.set_transient_for(parent)
  896.         self.parent = parent
  897.         self.button_cdrom_close.set_sensitive(False)
  898.  
  899.     
  900.     def close(self):
  901.         self.dialog_cdrom_progress.hide()
  902.  
  903.     
  904.     def on_button_cdrom_close_clicked(self, widget):
  905.         self.close()
  906.  
  907.     
  908.     def update(self, text, step):
  909.         ''' update is called regularly so that the gui can be redrawn '''
  910.         if step > 0:
  911.             self.progressbar_cdrom.set_fraction(step / float(self.totalSteps))
  912.             if step == self.totalSteps:
  913.                 self.button_cdrom_close.set_sensitive(True)
  914.             
  915.         
  916.         if text != '':
  917.             self.label_cdrom.set_text(text)
  918.         
  919.         while gtk.events_pending():
  920.             gtk.main_iteration()
  921.  
  922.     
  923.     def askCdromName(self):
  924.         dialog = gtk.MessageDialog(parent = self.dialog_cdrom_progress, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_QUESTION, buttons = gtk.BUTTONS_OK_CANCEL, message_format = None)
  925.         dialog.set_markup(_('Please enter a name for the disc'))
  926.         entry = gtk.Entry()
  927.         entry.show()
  928.         dialog.vbox.pack_start(entry)
  929.         res = dialog.run()
  930.         dialog.destroy()
  931.         if res == gtk.RESPONSE_OK:
  932.             name = entry.get_text()
  933.             return (True, name)
  934.         
  935.         return (False, '')
  936.  
  937.     
  938.     def changeCdrom(self):
  939.         dialog = gtk.MessageDialog(parent = self.dialog_cdrom_progress, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_QUESTION, buttons = gtk.BUTTONS_OK_CANCEL, message_format = None)
  940.         dialog.set_markup(_('Please insert a disc in the drive:'))
  941.         res = dialog.run()
  942.         dialog.destroy()
  943.         if res == gtk.RESPONSE_OK:
  944.             return True
  945.         
  946.         return False
  947.  
  948.  
  949.