~kubuntu-packagers/software-properties/dbusworker

« back to all changes in this revision

Viewing changes to softwareproperties/kde/SoftwarePropertiesKDE.py

  • Committer: Harald Sitter
  • Date: 2010-08-24 13:31:05 UTC
  • Revision ID: apachelogger@ubuntu.com-20100824133105-q0so5v6n8sa3rmyu
convert KDEUI main file to 4 character indent

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
1
2
# -*- coding: utf-8 -*-
 
3
 
2
4
#
3
5
#  Qt 4 based frontend to software-properties
4
6
#
54
56
from DialogMirror import DialogMirror
55
57
from CdromProgress import CdromProgress
56
58
 
 
59
 
57
60
class SoftwarePropertiesKDEUI(QWidget):
58
 
  def __init__(self, datadir):
59
 
      QWidget.__init__(self)
60
 
      uic.loadUi("%s/designer/main.ui" % datadir, self)
 
61
 
 
62
    def __init__(self, datadir):
 
63
        QWidget.__init__(self)
 
64
        uic.loadUi('%s/designer/main.ui' % datadir, self)
 
65
 
61
66
 
62
67
class SoftwarePropertiesKDE(SoftwareProperties):
63
 
  def __init__(self, datadir=None, options=None, parent=None, file=None, attachWinID=None):
64
 
    """ Provide a KDE based graphical user interface to configure
 
68
 
 
69
    def __init__(
 
70
        self,
 
71
        datadir=None,
 
72
        options=None,
 
73
        parent=None,
 
74
        file=None,
 
75
        attachWinID=None,
 
76
        ):
 
77
        """ Provide a KDE based graphical user interface to configure
65
78
        the used software repositories, corresponding authentication keys
66
79
        and update automation """
67
 
    SoftwareProperties.__init__(self, options=options, datadir=datadir)
68
 
 
69
 
    self.options = options
70
 
    self.datadir = datadir
71
 
 
72
 
    global kapp
73
 
    kapp = KApplication()
74
 
 
75
 
    self.userinterface = SoftwarePropertiesKDEUI(datadir)
76
 
    self.userinterface.setWindowIcon(KIcon("applications-other"))
77
 
    self.userinterface.button_auth_restore.setIcon(KIcon("edit-undo"))
78
 
    self.userinterface.button_add_auth.setIcon(KIcon("list-add"))
79
 
    self.userinterface.button_auth_remove.setIcon(KIcon("list-remove"))
80
 
    self.userinterface.button_remove.setIcon(KIcon("list-remove"))
81
 
    self.userinterface.button_edit.setIcon(KIcon("document-edit"))
82
 
    self.userinterface.button_add.setIcon(KIcon("list-add"))
83
 
    self.userinterface.button_add_cdrom.setIcon(KIcon("media-optical"))
84
 
    translate_widget(self.userinterface)
85
 
    self.userinterface.show()
86
 
    if attachWinID is not None:
87
 
        KWindowSystem.setMainWindow(self.userinterface, int(attachWinID))
 
80
 
 
81
        SoftwareProperties.__init__(self, options=options,
 
82
                                    datadir=datadir)
 
83
 
 
84
        self.options = options
 
85
        self.datadir = datadir
 
86
 
 
87
        global kapp
 
88
        kapp = KApplication()
 
89
 
 
90
        self.userinterface = SoftwarePropertiesKDEUI(datadir)
 
91
        self.userinterface.setWindowIcon(KIcon('applications-other'))
 
92
        self.userinterface.button_auth_restore.setIcon(KIcon('edit-undo'
 
93
                ))
 
94
        self.userinterface.button_add_auth.setIcon(KIcon('list-add'))
 
95
        self.userinterface.button_auth_remove.setIcon(KIcon('list-remove'
 
96
                ))
 
97
        self.userinterface.button_remove.setIcon(KIcon('list-remove'))
 
98
        self.userinterface.button_edit.setIcon(KIcon('document-edit'))
 
99
        self.userinterface.button_add.setIcon(KIcon('list-add'))
 
100
        self.userinterface.button_add_cdrom.setIcon(KIcon('media-optical'
 
101
                ))
 
102
        translate_widget(self.userinterface)
 
103
        self.userinterface.show()
 
104
        if attachWinID is not None:
 
105
            KWindowSystem.setMainWindow(self.userinterface,
 
106
                    int(attachWinID))
88
107
 
89
108
    # rejected() signal from Close button
90
 
    kapp.connect(self.userinterface.buttonBox, SIGNAL("rejected()"), self.on_close_button)
91
 
 
92
 
    self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
 
109
 
 
110
        kapp.connect(self.userinterface.buttonBox, SIGNAL('rejected()'
 
111
                     ), self.on_close_button)
 
112
 
 
113
        self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
93
114
 
94
115
    # Put some life into the user interface:
95
 
    self.init_server_chooser()
96
 
    self.init_popcon()
97
 
    self.init_auto_update()
98
 
    self.show_auto_update_level()
 
116
 
 
117
        self.init_server_chooser()
 
118
        self.init_popcon()
 
119
        self.init_auto_update()
 
120
        self.show_auto_update_level()
 
121
 
99
122
    # Setup the key list
100
 
    self.init_keys()
101
 
    self.show_keys()
 
123
 
 
124
        self.init_keys()
 
125
        self.show_keys()
 
126
 
102
127
    # Setup the ISV sources list
103
 
    self.init_isv_sources()
104
 
    self.show_isv_sources()
105
 
    self.show_cdrom_sources()
106
 
 
107
 
    kapp.connect(self.userinterface.checkbutton_source_code, SIGNAL("clicked()"), self.on_checkbutton_source_code_toggled)
108
 
    kapp.connect(self.userinterface.button_auth_restore, SIGNAL("clicked()"), self.on_restore_clicked)
109
 
    kapp.connect(self.userinterface.button_add_auth, SIGNAL("clicked()"), self.add_key_clicked)
110
 
    kapp.connect(self.userinterface.button_auth_remove, SIGNAL("clicked()"), self.remove_key_clicked)
111
 
    kapp.connect(self.userinterface.checkbutton_popcon, SIGNAL("toggled(bool)"), self.on_checkbutton_popcon_toggled)
112
 
    kapp.connect(self.userinterface.checkbutton_auto_update, SIGNAL("toggled(bool)"), self.on_auto_update_toggled)
113
 
    kapp.connect(self.userinterface.combobox_update_interval, SIGNAL("currentIndexChanged(int)"), self.on_combobox_update_interval_changed)
114
 
    kapp.connect(self.userinterface.button_remove, SIGNAL("clicked()"), self.on_remove_clicked)
115
 
    kapp.connect(self.userinterface.button_edit, SIGNAL("clicked()"), self.on_edit_clicked)
116
 
    kapp.connect(self.userinterface.button_add_cdrom, SIGNAL("clicked()"), self.on_button_add_cdrom_clicked)
117
 
    kapp.connect(self.userinterface.button_add, SIGNAL("clicked()"), self.on_add_clicked)
118
 
    kapp.connect(self.userinterface.treeview_sources, SIGNAL("itemChanged(QTreeWidgetItem*, int)"), self.on_isv_source_toggled)
119
 
    kapp.connect(self.userinterface.treeview_sources, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), self.on_treeview_sources_cursor_changed)
120
 
    kapp.connect(self.userinterface.treeview_cdroms, SIGNAL("itemChanged(QTreeWidgetItem*, int)"), self.on_cdrom_source_toggled)
121
 
    kapp.connect(self.userinterface.treeview2, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), self.on_treeview_keys_cursor_changed)
122
 
    button_close = self.userinterface.buttonBox.button(QDialogButtonBox.Close)
123
 
    button_close.setIcon(KIcon("dialog-close"))
124
 
    button_revert = self.userinterface.buttonBox.button(QDialogButtonBox.Reset)
125
 
    button_revert.setIcon(KIcon("edit-undo"))
126
 
    kapp.connect(button_revert, SIGNAL("clicked()"), self.on_button_revert_clicked)
127
 
 
128
 
    self.init_distro()
129
 
    self.show_distro()
130
 
 
131
 
  def init_popcon(self):
132
 
    """ If popcon is enabled show the statistics tab and an explanation
 
128
 
 
129
        self.init_isv_sources()
 
130
        self.show_isv_sources()
 
131
        self.show_cdrom_sources()
 
132
 
 
133
        kapp.connect(self.userinterface.checkbutton_source_code,
 
134
                     SIGNAL('clicked()'),
 
135
                     self.on_checkbutton_source_code_toggled)
 
136
        kapp.connect(self.userinterface.button_auth_restore,
 
137
                     SIGNAL('clicked()'), self.on_restore_clicked)
 
138
        kapp.connect(self.userinterface.button_add_auth,
 
139
                     SIGNAL('clicked()'), self.add_key_clicked)
 
140
        kapp.connect(self.userinterface.button_auth_remove,
 
141
                     SIGNAL('clicked()'), self.remove_key_clicked)
 
142
        kapp.connect(self.userinterface.checkbutton_popcon,
 
143
                     SIGNAL('toggled(bool)'),
 
144
                     self.on_checkbutton_popcon_toggled)
 
145
        kapp.connect(self.userinterface.checkbutton_auto_update,
 
146
                     SIGNAL('toggled(bool)'),
 
147
                     self.on_auto_update_toggled)
 
148
        kapp.connect(self.userinterface.combobox_update_interval,
 
149
                     SIGNAL('currentIndexChanged(int)'),
 
150
                     self.on_combobox_update_interval_changed)
 
151
        kapp.connect(self.userinterface.button_remove,
 
152
                     SIGNAL('clicked()'), self.on_remove_clicked)
 
153
        kapp.connect(self.userinterface.button_edit, SIGNAL('clicked()'
 
154
                     ), self.on_edit_clicked)
 
155
        kapp.connect(self.userinterface.button_add_cdrom,
 
156
                     SIGNAL('clicked()'),
 
157
                     self.on_button_add_cdrom_clicked)
 
158
        kapp.connect(self.userinterface.button_add, SIGNAL('clicked()'
 
159
                     ), self.on_add_clicked)
 
160
        kapp.connect(self.userinterface.treeview_sources,
 
161
                     SIGNAL('itemChanged(QTreeWidgetItem*, int)'),
 
162
                     self.on_isv_source_toggled)
 
163
        kapp.connect(self.userinterface.treeview_sources,
 
164
                     SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
 
165
                     self.on_treeview_sources_cursor_changed)
 
166
        kapp.connect(self.userinterface.treeview_cdroms,
 
167
                     SIGNAL('itemChanged(QTreeWidgetItem*, int)'),
 
168
                     self.on_cdrom_source_toggled)
 
169
        kapp.connect(self.userinterface.treeview2,
 
170
                     SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
 
171
                     self.on_treeview_keys_cursor_changed)
 
172
        button_close = \
 
173
            self.userinterface.buttonBox.button(QDialogButtonBox.Close)
 
174
        button_close.setIcon(KIcon('dialog-close'))
 
175
        button_revert = \
 
176
            self.userinterface.buttonBox.button(QDialogButtonBox.Reset)
 
177
        button_revert.setIcon(KIcon('edit-undo'))
 
178
        kapp.connect(button_revert, SIGNAL('clicked()'),
 
179
                     self.on_button_revert_clicked)
 
180
 
 
181
        self.init_distro()
 
182
        self.show_distro()
 
183
 
 
184
    def init_popcon(self):
 
185
        """ If popcon is enabled show the statistics tab and an explanation
133
186
        corresponding to the used distro """
134
 
    is_helpful = self.get_popcon_participation()
135
 
    if is_helpful != None:
136
 
      text = softwareproperties.distro.get_popcon_description(self.distro)
137
 
      text = text.replace("\n", "<br />") #silly GTK mixes HTML and normal white space
138
 
      self.userinterface.label_popcon_desc.setText(utf8(text))
139
 
      self.userinterface.checkbutton_popcon.setChecked(is_helpful)
140
 
    else:
141
 
      self.userinterface.tabWidget.removeTab(4)
142
 
 
143
 
  def init_server_chooser(self):
144
 
    """ Set up the widgets that allow to choose an alternate download site """
 
187
 
 
188
        is_helpful = self.get_popcon_participation()
 
189
        if is_helpful != None:
 
190
            text = \
 
191
                softwareproperties.distro.get_popcon_description(self.distro)
 
192
            text = text.replace('\n', '<br />')  # silly GTK mixes HTML and normal white space
 
193
            self.userinterface.label_popcon_desc.setText(utf8(text))
 
194
            self.userinterface.checkbutton_popcon.setChecked(is_helpful)
 
195
        else:
 
196
            self.userinterface.tabWidget.removeTab(4)
 
197
 
 
198
    def init_server_chooser(self):
 
199
        """ Set up the widgets that allow to choose an alternate download site """
 
200
 
145
201
    # nothing to do here, set up signal in show_distro()
146
 
    pass
147
 
 
148
 
  def init_auto_update(self):
149
 
    """ Set up the widgets that allow to configure the update automation """
 
202
 
 
203
        pass
 
204
 
 
205
    def init_auto_update(self):
 
206
        """ Set up the widgets that allow to configure the update automation """
 
207
 
150
208
    # this maps the key (combo-box-index) to the auto-update-interval value
151
209
    # where (-1) means, no key
152
 
    self.combobox_interval_mapping = { 0 : 1,
153
 
                                       1 : 2,
154
 
                                       2 : 7,
155
 
                                       3 : 14 }
156
 
 
157
 
    self.userinterface.combobox_update_interval.insertItem(99, utf8(_("Daily")))
158
 
    self.userinterface.combobox_update_interval.insertItem(99, utf8(_("Every two days")))
159
 
    self.userinterface.combobox_update_interval.insertItem(99, utf8(_("Weekly")))
160
 
    self.userinterface.combobox_update_interval.insertItem(99, utf8(_("Every two weeks")))
161
 
 
162
 
    update_days = self.get_update_interval()
 
210
 
 
211
        self.combobox_interval_mapping = {
 
212
            0: 1,
 
213
            1: 2,
 
214
            2: 7,
 
215
            3: 14,
 
216
            }
 
217
 
 
218
        self.userinterface.combobox_update_interval.insertItem(99,
 
219
                utf8(_('Daily')))
 
220
        self.userinterface.combobox_update_interval.insertItem(99,
 
221
                utf8(_('Every two days')))
 
222
        self.userinterface.combobox_update_interval.insertItem(99,
 
223
                utf8(_('Weekly')))
 
224
        self.userinterface.combobox_update_interval.insertItem(99,
 
225
                utf8(_('Every two weeks')))
 
226
 
 
227
        update_days = self.get_update_interval()
163
228
 
164
229
    # If a custom period is defined add a corresponding entry
165
 
    if not update_days in self.combobox_interval_mapping.values():
166
 
        if update_days > 0:
167
 
            self.userinterface.combobox_update_interval.insertItem(99, utf8(_("Every %s days")) % update_days)
168
 
            self.combobox_interval_mapping[4] = update_days
169
 
 
170
 
    for key in self.combobox_interval_mapping:
171
 
      if self.combobox_interval_mapping[key] == update_days:
172
 
        self.userinterface.combobox_update_interval.setCurrentIndex(key)
173
 
        break
174
 
 
175
 
    if update_days >= 1:
176
 
      self.userinterface.checkbutton_auto_update.setChecked(True)
177
 
      self.userinterface.combobox_update_interval.setEnabled(True)
178
 
      self.userinterface.radiobutton_updates_inst_sec.setEnabled(True)
179
 
      self.userinterface.radiobutton_updates_download.setEnabled(True)
180
 
      self.userinterface.radiobutton_updates_notify.setEnabled(True)
181
 
    else:
182
 
      self.userinterface.checkbutton_auto_update.setChecked(False)
183
 
      self.userinterface.combobox_update_interval.setEnabled(False)
184
 
      self.userinterface.radiobutton_updates_inst_sec.setEnabled(False)
185
 
      self.userinterface.radiobutton_updates_download.setEnabled(False)
186
 
      self.userinterface.radiobutton_updates_notify.setEnabled(False)
187
 
 
188
 
    kapp.connect(self.userinterface.radiobutton_updates_download, SIGNAL("toggled(bool)"), self.set_update_automation_level)
189
 
    kapp.connect(self.userinterface.radiobutton_updates_inst_sec, SIGNAL("toggled(bool)"), self.set_update_automation_level)
190
 
    kapp.connect(self.userinterface.radiobutton_updates_notify, SIGNAL("toggled(bool)"), self.set_update_automation_level)
191
 
 
192
 
  def show_auto_update_level(self):
193
 
    """Represent the level of update automation in the user interface"""
194
 
    level = self.get_update_automation_level()
195
 
    if level == None:
196
 
        self.userinterface.radiobutton_updates_inst_sec.setChecked(False)
197
 
        self.userinterface.radiobutton_updates_download.setChecked(False)
198
 
        self.userinterface.radiobutton_updates_notify.setChecked(False)
199
 
    if level == softwareproperties.UPDATE_MANUAL or\
200
 
       level == softwareproperties.UPDATE_NOTIFY:
201
 
        self.userinterface.radiobutton_updates_notify.setChecked(True)
202
 
    elif level == softwareproperties.UPDATE_DOWNLOAD:
203
 
        self.userinterface.radiobutton_updates_download.setChecked(True)
204
 
    elif level == softwareproperties.UPDATE_INST_SEC:
205
 
        self.userinterface.radiobutton_updates_inst_sec.setChecked(True)
206
 
 
207
 
  def init_distro(self):
208
 
    # TRANS: %s stands for the distribution name e.g. Debian or Ubuntu
209
 
    text = u_("%s updates") % self.distro.id
210
 
    text = text.replace("Ubuntu", "Kubuntu")
211
 
    self.userinterface.groupBox_updates.setTitle(text)
212
 
    # TRANS: %s stands for the distribution name e.g. Debian or Ubuntu
213
 
    text = u_("%s Software") % self.distro.id
214
 
    text = text.replace("Ubuntu", "Kubuntu")
215
 
    self.userinterface.tabWidget.setTabText(0, text)
 
230
 
 
231
        if not update_days in self.combobox_interval_mapping.values():
 
232
            if update_days > 0:
 
233
                self.userinterface.combobox_update_interval.insertItem(99,
 
234
                        utf8(_('Every %s days')) % update_days)
 
235
                self.combobox_interval_mapping[4] = update_days
 
236
 
 
237
        for key in self.combobox_interval_mapping:
 
238
            if self.combobox_interval_mapping[key] == update_days:
 
239
                self.userinterface.combobox_update_interval.setCurrentIndex(key)
 
240
                break
 
241
 
 
242
        if update_days >= 1:
 
243
            self.userinterface.checkbutton_auto_update.setChecked(True)
 
244
            self.userinterface.combobox_update_interval.setEnabled(True)
 
245
            self.userinterface.radiobutton_updates_inst_sec.setEnabled(True)
 
246
            self.userinterface.radiobutton_updates_download.setEnabled(True)
 
247
            self.userinterface.radiobutton_updates_notify.setEnabled(True)
 
248
        else:
 
249
            self.userinterface.checkbutton_auto_update.setChecked(False)
 
250
            self.userinterface.combobox_update_interval.setEnabled(False)
 
251
            self.userinterface.radiobutton_updates_inst_sec.setEnabled(False)
 
252
            self.userinterface.radiobutton_updates_download.setEnabled(False)
 
253
            self.userinterface.radiobutton_updates_notify.setEnabled(False)
 
254
 
 
255
        kapp.connect(self.userinterface.radiobutton_updates_download,
 
256
                     SIGNAL('toggled(bool)'),
 
257
                     self.set_update_automation_level)
 
258
        kapp.connect(self.userinterface.radiobutton_updates_inst_sec,
 
259
                     SIGNAL('toggled(bool)'),
 
260
                     self.set_update_automation_level)
 
261
        kapp.connect(self.userinterface.radiobutton_updates_notify,
 
262
                     SIGNAL('toggled(bool)'),
 
263
                     self.set_update_automation_level)
 
264
 
 
265
    def show_auto_update_level(self):
 
266
        """Represent the level of update automation in the user interface"""
 
267
 
 
268
        level = self.get_update_automation_level()
 
269
        if level == None:
 
270
            self.userinterface.radiobutton_updates_inst_sec.setChecked(False)
 
271
            self.userinterface.radiobutton_updates_download.setChecked(False)
 
272
            self.userinterface.radiobutton_updates_notify.setChecked(False)
 
273
        if level == softwareproperties.UPDATE_MANUAL or level \
 
274
            == softwareproperties.UPDATE_NOTIFY:
 
275
            self.userinterface.radiobutton_updates_notify.setChecked(True)
 
276
        elif level == softwareproperties.UPDATE_DOWNLOAD:
 
277
            self.userinterface.radiobutton_updates_download.setChecked(True)
 
278
        elif level == softwareproperties.UPDATE_INST_SEC:
 
279
            self.userinterface.radiobutton_updates_inst_sec.setChecked(True)
 
280
 
 
281
    def init_distro(self):
 
282
 
 
283
    # TRANS: %s stands for the distribution name e.g. Debian or Ubuntu
 
284
 
 
285
        text = u_('%s updates') % self.distro.id
 
286
        text = text.replace('Ubuntu', 'Kubuntu')
 
287
        self.userinterface.groupBox_updates.setTitle(text)
 
288
 
 
289
    # TRANS: %s stands for the distribution name e.g. Debian or Ubuntu
 
290
 
 
291
        text = u_('%s Software') % self.distro.id
 
292
        text = text.replace('Ubuntu', 'Kubuntu')
 
293
        self.userinterface.tabWidget.setTabText(0, text)
216
294
 
217
295
    # Setup the checkbuttons for the components
218
 
    for child in self.userinterface.vbox_dist_comps_frame.children():
219
 
        if isinstance(child, QGridLayout):
220
 
            self.vbox_dist_comps = child
221
 
        elif isinstance(child, QObject):
222
 
            print "passing"
223
 
        else:
224
 
            print "chidl: " + str(type(child))
225
 
            child.hide()
226
 
            del child
227
 
    self.checkboxComps = {}
228
 
    for comp in self.distro.source_template.components:
 
296
 
 
297
        for child in \
 
298
            self.userinterface.vbox_dist_comps_frame.children():
 
299
            if isinstance(child, QGridLayout):
 
300
                self.vbox_dist_comps = child
 
301
            elif isinstance(child, QObject):
 
302
                print 'passing'
 
303
            else:
 
304
                print 'chidl: ' + str(type(child))
 
305
                child.hide()
 
306
                del child
 
307
        self.checkboxComps = {}
 
308
        for comp in self.distro.source_template.components:
 
309
 
229
310
        # TRANSLATORS: Label for the components in the Internet section
230
311
        #              first %s is the description of the component
231
312
        #              second %s is the code name of the comp, eg main, universe
232
 
        label = _("%s (%s)") % (comp.get_description(), comp.name)
233
 
        checkbox = QCheckBox(utf8(label), self.userinterface.vbox_dist_comps_frame)
234
 
        checkbox.setObjectName(comp.name)
235
 
        self.checkboxComps[checkbox] = comp
 
313
 
 
314
            label = _('%s (%s)') % (comp.get_description(), comp.name)
 
315
            checkbox = QCheckBox(utf8(label),
 
316
                                 self.userinterface.vbox_dist_comps_frame)
 
317
            checkbox.setObjectName(comp.name)
 
318
            self.checkboxComps[checkbox] = comp
236
319
 
237
320
        # setup the callback and show the checkbutton
238
 
        kapp.connect(checkbox, SIGNAL("clicked()"), self.on_component_toggled)
239
 
        self.vbox_dist_comps.addWidget(checkbox)
 
321
 
 
322
            kapp.connect(checkbox, SIGNAL('clicked()'),
 
323
                         self.on_component_toggled)
 
324
            self.vbox_dist_comps.addWidget(checkbox)
240
325
 
241
326
    # Setup the checkbuttons for the child repos / updates
242
 
    for child in self.userinterface.vbox_updates_frame.children():
243
 
        if isinstance(child, QGridLayout):
244
 
            self.vbox_updates = child
245
 
        else:
246
 
            del child
247
 
    if len(self.distro.source_template.children) < 1:
248
 
        self.userinterface.vbox_updates_frame.hide()
249
 
    self.checkboxTemplates = {}
250
 
    for template in self.distro.source_template.children:
251
 
        checkbox = QCheckBox(utf8(template.description), 
252
 
                             self.userinterface.vbox_updates_frame)
253
 
        checkbox.setObjectName(template.name)
254
 
        self.checkboxTemplates[checkbox] = template
 
327
 
 
328
        for child in self.userinterface.vbox_updates_frame.children():
 
329
            if isinstance(child, QGridLayout):
 
330
                self.vbox_updates = child
 
331
            else:
 
332
                del child
 
333
        if len(self.distro.source_template.children) < 1:
 
334
            self.userinterface.vbox_updates_frame.hide()
 
335
        self.checkboxTemplates = {}
 
336
        for template in self.distro.source_template.children:
 
337
            checkbox = QCheckBox(utf8(template.description),
 
338
                                 self.userinterface.vbox_updates_frame)
 
339
            checkbox.setObjectName(template.name)
 
340
            self.checkboxTemplates[checkbox] = template
 
341
 
255
342
        # setup the callback and show the checkbutton
256
 
        kapp.connect(checkbox, SIGNAL("clicked()"), self.on_checkbutton_child_toggled)
257
 
        self.vbox_updates.addWidget(checkbox)
 
343
 
 
344
            kapp.connect(checkbox, SIGNAL('clicked()'),
 
345
                         self.on_checkbutton_child_toggled)
 
346
            self.vbox_updates.addWidget(checkbox)
258
347
 
259
348
    # If no components are enabled there will be no need for updates
260
 
    if len(self.distro.enabled_comps) < 1:
261
 
        self.userinterface.vbox_updates_frame.setEnabled(False)
262
 
    else:
263
 
        self.userinterface.vbox_updates_frame.setEnabled(True)
264
 
 
265
 
    self.init_mirrors()
266
 
    kapp.connect(self.userinterface.combobox_server, SIGNAL("activated(int)"), self.on_combobox_server_changed)
267
 
 
268
 
  def init_mirrors(self):
 
349
 
 
350
        if len(self.distro.enabled_comps) < 1:
 
351
            self.userinterface.vbox_updates_frame.setEnabled(False)
 
352
        else:
 
353
            self.userinterface.vbox_updates_frame.setEnabled(True)
 
354
 
 
355
        self.init_mirrors()
 
356
        kapp.connect(self.userinterface.combobox_server,
 
357
                     SIGNAL('activated(int)'),
 
358
                     self.on_combobox_server_changed)
 
359
 
 
360
    def init_mirrors(self):
 
361
 
269
362
    # Intiate the combobox which allows the user to specify a server for all
270
363
    # distro related sources
271
 
    seen_server_new = []
272
 
    self.mirror_urls = []
273
 
    self.userinterface.combobox_server.clear()
274
 
    for (name, uri, active) in self.distro.get_server_list():
275
 
        ##server_store.append([name, uri, False])
276
 
        self.userinterface.combobox_server.addItem(utf8(name))
277
 
        self.mirror_urls.append(uri)
278
 
        if [name, uri] in self.seen_server:
279
 
            self.seen_server.remove([name, uri])
280
 
        elif uri != None:
281
 
            seen_server_new.append([name, uri])
282
 
        if active == True:
283
 
            self.active_server = self.userinterface.combobox_server.count() - 1
284
 
            self.userinterface.combobox_server.setCurrentIndex(self.userinterface.combobox_server.count() - 1)
285
 
    for [name, uri] in self.seen_server:
286
 
        self.userinterface.combobox_server.addItem(utf8(name))
287
 
        self.mirror_urls.append(uri)
288
 
    self.seen_server = seen_server_new
 
364
 
 
365
        seen_server_new = []
 
366
        self.mirror_urls = []
 
367
        self.userinterface.combobox_server.clear()
 
368
        for (name, uri, active) in self.distro.get_server_list():
 
369
 
 
370
        # #server_store.append([name, uri, False])
 
371
 
 
372
            self.userinterface.combobox_server.addItem(utf8(name))
 
373
            self.mirror_urls.append(uri)
 
374
            if [name, uri] in self.seen_server:
 
375
                self.seen_server.remove([name, uri])
 
376
            elif uri != None:
 
377
                seen_server_new.append([name, uri])
 
378
            if active == True:
 
379
                self.active_server = \
 
380
                    self.userinterface.combobox_server.count() - 1
 
381
                self.userinterface.combobox_server.setCurrentIndex(self.userinterface.combobox_server.count()
 
382
                        - 1)
 
383
        for [name, uri] in self.seen_server:
 
384
            self.userinterface.combobox_server.addItem(utf8(name))
 
385
            self.mirror_urls.append(uri)
 
386
        self.seen_server = seen_server_new
 
387
 
289
388
    # add a separator and the option to choose another mirror from the list
290
 
    ##FIXME server_store.append(["sep", None, True])
291
 
    self.userinterface.combobox_server.addItem(utf8(_("Other...")))
292
 
    self.other_mirrors_index = self.userinterface.combobox_server.count() - 1
293
 
 
294
 
  def show_distro(self):
295
 
    """
 
389
    # #FIXME server_store.append(["sep", None, True])
 
390
 
 
391
        self.userinterface.combobox_server.addItem(utf8(_('Other...')))
 
392
        self.other_mirrors_index = \
 
393
            self.userinterface.combobox_server.count() - 1
 
394
 
 
395
    def show_distro(self):
 
396
        """
296
397
    Represent the distro information in the user interface
297
398
    """
 
399
 
298
400
    # Enable or disable the child source checkbuttons
299
 
    for child in self.userinterface.vbox_updates_frame.children():
300
 
        if isinstance(child, QCheckBox):
301
 
            template = self.checkboxTemplates[child]
302
 
            (active, inconsistent) = self.get_comp_child_state(template)
303
 
            if inconsistent:
304
 
                child.setCheckState(Qt.PartiallyChecked)
305
 
            elif active:
306
 
                child.setCheckState(Qt.Checked)
307
 
            else:
308
 
                child.setCheckState(Qt.Unchecked)
 
401
 
 
402
        for child in self.userinterface.vbox_updates_frame.children():
 
403
            if isinstance(child, QCheckBox):
 
404
                template = self.checkboxTemplates[child]
 
405
                (active, inconsistent) = \
 
406
                    self.get_comp_child_state(template)
 
407
                if inconsistent:
 
408
                    child.setCheckState(Qt.PartiallyChecked)
 
409
                elif active:
 
410
                    child.setCheckState(Qt.Checked)
 
411
                else:
 
412
                    child.setCheckState(Qt.Unchecked)
309
413
 
310
414
    # Enable or disable the component checkbuttons
311
 
    for child in self.userinterface.vbox_dist_comps_frame.children():
312
 
        if isinstance(child, QCheckBox):
313
 
            template = self.checkboxComps[child]
314
 
            (active, inconsistent) = self.get_comp_download_state(template)
315
 
            if inconsistent:
316
 
                child.setCheckState(Qt.PartiallyChecked)
317
 
            elif active:
318
 
                child.setCheckState(Qt.Checked)
319
 
            else:
320
 
                child.setCheckState(Qt.Unchecked)
 
415
 
 
416
        for child in \
 
417
            self.userinterface.vbox_dist_comps_frame.children():
 
418
            if isinstance(child, QCheckBox):
 
419
                template = self.checkboxComps[child]
 
420
                (active, inconsistent) = \
 
421
                    self.get_comp_download_state(template)
 
422
                if inconsistent:
 
423
                    child.setCheckState(Qt.PartiallyChecked)
 
424
                elif active:
 
425
                    child.setCheckState(Qt.Checked)
 
426
                else:
 
427
                    child.setCheckState(Qt.Unchecked)
321
428
 
322
429
    # If no components are enabled there will be no need for updates
323
430
    # and source code
324
 
    if len(self.distro.enabled_comps) < 1:
325
 
        self.userinterface.vbox_updates_frame.setEnabled(False)
326
 
        self.userinterface.checkbutton_source_code.setEnabled(False)
327
 
    else:
328
 
        self.userinterface.vbox_updates_frame.setEnabled(True)
329
 
        self.userinterface.checkbutton_source_code.setEnabled(True)
 
431
 
 
432
        if len(self.distro.enabled_comps) < 1:
 
433
            self.userinterface.vbox_updates_frame.setEnabled(False)
 
434
            self.userinterface.checkbutton_source_code.setEnabled(False)
 
435
        else:
 
436
            self.userinterface.vbox_updates_frame.setEnabled(True)
 
437
            self.userinterface.checkbutton_source_code.setEnabled(True)
330
438
 
331
439
    # Check for source code sources
332
 
    source_code_state = self.get_source_code_state()
333
 
    if source_code_state == True:
334
 
        self.userinterface.checkbutton_source_code.setCheckState(Qt.Checked)
335
 
    elif source_code_state == None:
336
 
        self.userinterface.checkbutton_source_code.setCheckState(Qt.PartiallyChecked)
337
 
    else:
338
 
        self.userinterface.checkbutton_source_code.setCheckState(Qt.Unchecked)
 
440
 
 
441
        source_code_state = self.get_source_code_state()
 
442
        if source_code_state == True:
 
443
            self.userinterface.checkbutton_source_code.setCheckState(Qt.Checked)
 
444
        elif source_code_state == None:
 
445
            self.userinterface.checkbutton_source_code.setCheckState(Qt.PartiallyChecked)
 
446
        else:
 
447
            self.userinterface.checkbutton_source_code.setCheckState(Qt.Unchecked)
339
448
 
340
449
    # Will show a short explanation if no CDROMs are used
341
 
    if len(self.get_cdrom_sources()) == 0:
342
 
        self.userinterface.treeview_cdroms.hide()
343
 
        self.userinterface.textview_no_cd.show()
344
 
        self.userinterface.groupBox_cdrom.hide()
345
 
    else:
346
 
        self.userinterface.treeview_cdroms.show()
347
 
        self.userinterface.textview_no_cd.hide()
348
 
        self.userinterface.groupBox_cdrom.show()
 
450
 
 
451
        if len(self.get_cdrom_sources()) == 0:
 
452
            self.userinterface.treeview_cdroms.hide()
 
453
            self.userinterface.textview_no_cd.show()
 
454
            self.userinterface.groupBox_cdrom.hide()
 
455
        else:
 
456
            self.userinterface.treeview_cdroms.show()
 
457
            self.userinterface.textview_no_cd.hide()
 
458
            self.userinterface.groupBox_cdrom.show()
349
459
 
350
460
    # Output a lot of debug stuff
351
 
    if self.options.debug == True or self.options.massive_debug == True:
352
 
        print "ENABLED COMPS: %s" % self.distro.enabled_comps
353
 
        print "INTERNET COMPS: %s" % self.distro.download_comps
354
 
        print "MAIN SOURCES"
355
 
        for source in self.distro.main_sources:
356
 
            self.print_source_entry(source)
357
 
        print "CHILD SOURCES"
358
 
        for source in self.distro.child_sources:
359
 
            self.print_source_entry(source)
360
 
        print "CDROM SOURCES"
361
 
        for source in self.distro.cdrom_sources:
362
 
            self.print_source_entry(source)
363
 
        print "SOURCE CODE SOURCES"
364
 
        for source in self.distro.source_code_sources:
365
 
            self.print_source_entry(source)
366
 
        print "DISABLED SOURCES"
367
 
        for source in self.distro.disabled_sources:
368
 
            self.print_source_entry(source)
369
 
        print "ISV"
370
 
        for source in self.sourceslist_visible:
371
 
            self.print_source_entry(source)
372
 
 
373
 
  def set_update_automation_level(self, selected):
374
 
    """Call the backend to set the update automation level to the given 
 
461
 
 
462
        if self.options.debug == True or self.options.massive_debug \
 
463
            == True:
 
464
            print 'ENABLED COMPS: %s' % self.distro.enabled_comps
 
465
            print 'INTERNET COMPS: %s' % self.distro.download_comps
 
466
            print 'MAIN SOURCES'
 
467
            for source in self.distro.main_sources:
 
468
                self.print_source_entry(source)
 
469
            print 'CHILD SOURCES'
 
470
            for source in self.distro.child_sources:
 
471
                self.print_source_entry(source)
 
472
            print 'CDROM SOURCES'
 
473
            for source in self.distro.cdrom_sources:
 
474
                self.print_source_entry(source)
 
475
            print 'SOURCE CODE SOURCES'
 
476
            for source in self.distro.source_code_sources:
 
477
                self.print_source_entry(source)
 
478
            print 'DISABLED SOURCES'
 
479
            for source in self.distro.disabled_sources:
 
480
                self.print_source_entry(source)
 
481
            print 'ISV'
 
482
            for source in self.sourceslist_visible:
 
483
                self.print_source_entry(source)
 
484
 
 
485
    def set_update_automation_level(self, selected):
 
486
        """Call the backend to set the update automation level to the given 
375
487
       value"""
376
 
    if self.userinterface.radiobutton_updates_download.isChecked():
377
 
        SoftwareProperties.set_update_automation_level(self, softwareproperties.UPDATE_DOWNLOAD)
378
 
    elif self.userinterface.radiobutton_updates_inst_sec.isChecked():
379
 
        SoftwareProperties.set_update_automation_level(self, softwareproperties.UPDATE_INST_SEC)
380
 
    elif self.userinterface.radiobutton_updates_notify.isChecked():
381
 
        SoftwareProperties.set_update_automation_level(self, softwareproperties.UPDATE_NOTIFY)
382
 
    self.set_modified_config()
383
 
 
384
 
  def on_combobox_server_changed(self, combobox):
385
 
    """
 
488
 
 
489
        if self.userinterface.radiobutton_updates_download.isChecked():
 
490
            SoftwareProperties.set_update_automation_level(self,
 
491
                    softwareproperties.UPDATE_DOWNLOAD)
 
492
        elif self.userinterface.radiobutton_updates_inst_sec.isChecked():
 
493
            SoftwareProperties.set_update_automation_level(self,
 
494
                    softwareproperties.UPDATE_INST_SEC)
 
495
        elif self.userinterface.radiobutton_updates_notify.isChecked():
 
496
            SoftwareProperties.set_update_automation_level(self,
 
497
                    softwareproperties.UPDATE_NOTIFY)
 
498
        self.set_modified_config()
 
499
 
 
500
    def on_combobox_server_changed(self, combobox):
 
501
        """
386
502
    Replace the servers used by the main and update sources with
387
503
    the selected one
388
504
    """
389
 
    combobox = self.userinterface.combobox_server
390
 
    index = combobox.currentIndex()
391
 
    if index == self.active_server:
392
 
        return
393
 
    elif index == self.other_mirrors_index:
394
 
        dialogue = DialogMirror(self.userinterface, self.datadir, self.distro, self.custom_mirrors)
395
 
        res = dialogue.run()
396
 
        if res != None:
397
 
            self.distro.change_server(res)
398
 
            self.set_modified_sourceslist()
399
 
            self.init_mirrors() # update combobox
400
 
        else:
401
 
            combobox.setCurrentIndex(self.active_server)
402
 
    else:
403
 
        uri = self.mirror_urls[index]
404
 
        if uri != None and len(self.distro.used_servers) > 0:
405
 
            self.active_server = index
406
 
            self.distro.change_server(uri)
407
 
            self.set_modified_sourceslist()
408
 
        else:
409
 
            self.distro.default_server = uri
410
 
 
411
 
  def on_component_toggled(self):
412
 
    """
 
505
 
 
506
        combobox = self.userinterface.combobox_server
 
507
        index = combobox.currentIndex()
 
508
        if index == self.active_server:
 
509
            return
 
510
        elif index == self.other_mirrors_index:
 
511
            dialogue = DialogMirror(self.userinterface, self.datadir,
 
512
                                    self.distro, self.custom_mirrors)
 
513
            res = dialogue.run()
 
514
            if res != None:
 
515
                self.distro.change_server(res)
 
516
                self.set_modified_sourceslist()
 
517
                self.init_mirrors()  # update combobox
 
518
            else:
 
519
                combobox.setCurrentIndex(self.active_server)
 
520
        else:
 
521
            uri = self.mirror_urls[index]
 
522
            if uri != None and len(self.distro.used_servers) > 0:
 
523
                self.active_server = index
 
524
                self.distro.change_server(uri)
 
525
                self.set_modified_sourceslist()
 
526
            else:
 
527
                self.distro.default_server = uri
 
528
 
 
529
    def on_component_toggled(self):
 
530
        """
413
531
    Sync the components of all main sources (excluding cdroms),
414
532
    child sources and source code sources
415
533
    """
416
 
    tickBox = kapp.sender()
417
 
    if tickBox.checkState() == Qt.Checked:
418
 
        self.enable_component(str(tickBox.objectName()))
419
 
    elif tickBox.checkState() == Qt.Unchecked:
420
 
        self.disable_component(str(tickBox.objectName()))
421
 
    self.set_modified_sourceslist()
 
534
 
 
535
        tickBox = kapp.sender()
 
536
        if tickBox.checkState() == Qt.Checked:
 
537
            self.enable_component(str(tickBox.objectName()))
 
538
        elif tickBox.checkState() == Qt.Unchecked:
 
539
            self.disable_component(str(tickBox.objectName()))
 
540
        self.set_modified_sourceslist()
422
541
 
423
542
    # no way to set back to mixed state so turn off tristate
424
 
    tickBox.setTristate(False)
425
 
 
426
 
  def on_checkbutton_child_toggled(self):
427
 
    """
 
543
 
 
544
        tickBox.setTristate(False)
 
545
 
 
546
    def on_checkbutton_child_toggled(self):
 
547
        """
428
548
    Enable or disable a child repo of the distribution main repository
429
549
    """
430
 
    tickBox = kapp.sender()
431
 
    name = str(tickBox.objectName())
432
 
    for template in self.distro.source_template.children:
433
 
        if name == template.name:
434
 
            aptTemplate = template
435
 
 
436
 
    if tickBox.checkState() == Qt.Checked:
437
 
        self.enable_child_source(aptTemplate)
438
 
    elif tickBox.checkState() == Qt.Unchecked:
439
 
        self.disable_child_source(aptTemplate)
 
550
 
 
551
        tickBox = kapp.sender()
 
552
        name = str(tickBox.objectName())
 
553
        for template in self.distro.source_template.children:
 
554
            if name == template.name:
 
555
                aptTemplate = template
 
556
 
 
557
        if tickBox.checkState() == Qt.Checked:
 
558
            self.enable_child_source(aptTemplate)
 
559
        elif tickBox.checkState() == Qt.Unchecked:
 
560
            self.disable_child_source(aptTemplate)
 
561
 
440
562
    # no way to set back to mixed state so turn off tristate
441
 
    tickBox.setTristate(False)
442
 
 
443
 
  def on_checkbutton_source_code_toggled(self):
444
 
    """ Disable or enable the source code for all sources """
445
 
    if self.userinterface.checkbutton_source_code.checkState() == Qt.Checked:
446
 
        self.enable_source_code_sources()
447
 
    elif self.userinterface.checkbutton_source_code.checkState() == Qt.Unchecked:
448
 
        self.disable_source_code_sources()
449
 
    self.userinterface.checkbutton_source_code.setTristate(False)
450
 
 
451
 
  def on_checkbutton_popcon_toggled(self, state):
452
 
    """ The user clicked on the popcon paritipcation button """
453
 
    self.set_popcon_pariticipation(state)
454
 
 
455
 
  def init_isv_sources(self):
456
 
    """Read all valid sources into our ListStore"""
457
 
    """##FIXME
458
 
    # drag and drop support for sources.list
459
 
    self.treeview_sources.drag_dest_set(gtk.DEST_DEFAULT_ALL, \
460
 
                                        [('text/uri-list',0, 0)], \
461
 
                                        gtk.gdk.ACTION_COPY)
462
 
    self.treeview_sources.connect("drag_data_received",\
463
 
                                  self.on_sources_drag_data_received)
464
 
    """
465
 
 
466
 
  def on_isv_source_activate(self, treeview, path, column):
467
 
    """Open the edit dialog if a channel was double clicked"""
468
 
    ##FIXME TODO
469
 
    ##self.on_edit_clicked(treeview)
470
 
 
471
 
  def on_treeview_sources_cursor_changed(self, item, column):
472
 
    """set the sensitiveness of the edit and remove button
473
 
       corresponding to the selected channel"""
474
 
    # allow to remove the selected channel
475
 
    self.userinterface.button_remove.setEnabled(True)
476
 
    # disable editing of cdrom sources
477
 
    index = self.userinterface.treeview_sources.indexOfTopLevelItem(item)
478
 
    source_entry = self.isv_sources[index]
479
 
    if source_entry.uri.startswith("cdrom:"):
480
 
        self.userinterface.button_edit.setEnabled(False)
481
 
    else:
482
 
        self.userinterface.button_edit.setEnabled(True)
483
 
 
484
 
  def on_cdrom_source_toggled(self, item):
485
 
    """Enable or disable the selected channel"""
486
 
    self.toggle_source(self.cdrom_sources, self.userinterface.treeview_cdroms, item)
487
 
 
488
 
  def on_isv_source_toggled(self, item):
489
 
    """Enable or disable the selected channel"""
490
 
    self.toggle_source(self.isv_sources, self.userinterface.treeview_sources, item)
491
 
 
492
 
  def toggle_source(self, sources, treeview, item):
493
 
    """Enable or disable the selected channel"""
494
 
    index = treeview.indexOfTopLevelItem(item)
495
 
    source_entry = sources[index]
496
 
    self.toggle_source_use(source_entry)
497
 
    item = treeview.topLevelItem(index) # old item was destroyed
498
 
    if item != 0:
499
 
      treeview.setCurrentItem(item) # reselect entry after refresh
500
 
    else:
501
 
      self.userinterface.button_remove.setEnabled(False)
502
 
      self.userinterface.button_edit.setEnabled(False)
503
 
 
504
 
  def init_keys(self):
505
 
    """Setup the user interface parts needed for the key handling"""
506
 
    self.userinterface.treeview2.setColumnCount(1)
507
 
 
508
 
  def on_treeview_keys_cursor_changed(self, item, column):
509
 
    """set the sensitiveness of the edit and remove button
510
 
       corresponding to the selected channel"""
511
 
    # allow to remove the selected channel
512
 
    self.userinterface.button_auth_remove.setEnabled(True)
513
 
    # disable editing of cdrom sources
514
 
    index = self.userinterface.treeview2.indexOfTopLevelItem(item)
515
 
 
516
 
  #FIXME revert automation settings too
517
 
  def on_button_revert_clicked(self):
518
 
    """Restore the source list from the startup of the dialog"""
519
 
    SoftwareProperties.revert(self)
520
 
    self.set_modified_sourceslist()
521
 
    self.show_auto_update_level()
522
 
    self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
523
 
    self.modified_sourceslist = False
524
 
 
525
 
  def set_modified_config(self):
526
 
    """The config was changed and now needs to be saved and reloaded"""
527
 
    SoftwareProperties.set_modified_config(self)
528
 
    self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
529
 
 
530
 
  def set_modified_sourceslist(self):
531
 
    """The sources list was changed and now needs to be saved and reloaded"""
532
 
    SoftwareProperties.set_modified_sourceslist(self)
533
 
    self.show_distro()
534
 
    self.show_isv_sources()
535
 
    self.show_cdrom_sources()
536
 
    self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
537
 
 
538
 
  def show_isv_sources(self):
539
 
    """ Show the repositories of independent software vendors in the
 
563
 
 
564
        tickBox.setTristate(False)
 
565
 
 
566
    def on_checkbutton_source_code_toggled(self):
 
567
        """ Disable or enable the source code for all sources """
 
568
 
 
569
        if self.userinterface.checkbutton_source_code.checkState() \
 
570
            == Qt.Checked:
 
571
            self.enable_source_code_sources()
 
572
        elif self.userinterface.checkbutton_source_code.checkState() \
 
573
            == Qt.Unchecked:
 
574
            self.disable_source_code_sources()
 
575
        self.userinterface.checkbutton_source_code.setTristate(False)
 
576
 
 
577
    def on_checkbutton_popcon_toggled(self, state):
 
578
        """ The user clicked on the popcon paritipcation button """
 
579
 
 
580
        self.set_popcon_pariticipation(state)
 
581
 
 
582
    def init_isv_sources(self):
 
583
        """Read all valid sources into our ListStore"""
 
584
 
 
585
    def on_isv_source_activate(
 
586
        self,
 
587
        treeview,
 
588
        path,
 
589
        column,
 
590
        ):
 
591
        """Open the edit dialog if a channel was double clicked"""
 
592
 
 
593
    # #FIXME TODO
 
594
    # #self.on_edit_clicked(treeview)
 
595
 
 
596
    def on_treeview_sources_cursor_changed(self, item, column):
 
597
        """set the sensitiveness of the edit and remove button
 
598
       corresponding to the selected channel"""
 
599
 
 
600
    # allow to remove the selected channel
 
601
 
 
602
        self.userinterface.button_remove.setEnabled(True)
 
603
 
 
604
    # disable editing of cdrom sources
 
605
 
 
606
        index = \
 
607
            self.userinterface.treeview_sources.indexOfTopLevelItem(item)
 
608
        source_entry = self.isv_sources[index]
 
609
        if source_entry.uri.startswith('cdrom:'):
 
610
            self.userinterface.button_edit.setEnabled(False)
 
611
        else:
 
612
            self.userinterface.button_edit.setEnabled(True)
 
613
 
 
614
    def on_cdrom_source_toggled(self, item):
 
615
        """Enable or disable the selected channel"""
 
616
 
 
617
        self.toggle_source(self.cdrom_sources,
 
618
                           self.userinterface.treeview_cdroms, item)
 
619
 
 
620
    def on_isv_source_toggled(self, item):
 
621
        """Enable or disable the selected channel"""
 
622
 
 
623
        self.toggle_source(self.isv_sources,
 
624
                           self.userinterface.treeview_sources, item)
 
625
 
 
626
    def toggle_source(
 
627
        self,
 
628
        sources,
 
629
        treeview,
 
630
        item,
 
631
        ):
 
632
        """Enable or disable the selected channel"""
 
633
 
 
634
        index = treeview.indexOfTopLevelItem(item)
 
635
        source_entry = sources[index]
 
636
        self.toggle_source_use(source_entry)
 
637
        item = treeview.topLevelItem(index)  # old item was destroyed
 
638
        if item != 0:
 
639
            treeview.setCurrentItem(item)  # reselect entry after refresh
 
640
        else:
 
641
            self.userinterface.button_remove.setEnabled(False)
 
642
            self.userinterface.button_edit.setEnabled(False)
 
643
 
 
644
    def init_keys(self):
 
645
        """Setup the user interface parts needed for the key handling"""
 
646
 
 
647
        self.userinterface.treeview2.setColumnCount(1)
 
648
 
 
649
    def on_treeview_keys_cursor_changed(self, item, column):
 
650
        """set the sensitiveness of the edit and remove button
 
651
       corresponding to the selected channel"""
 
652
 
 
653
    # allow to remove the selected channel
 
654
 
 
655
        self.userinterface.button_auth_remove.setEnabled(True)
 
656
 
 
657
    # disable editing of cdrom sources
 
658
 
 
659
        index = self.userinterface.treeview2.indexOfTopLevelItem(item)
 
660
 
 
661
  # FIXME revert automation settings too
 
662
 
 
663
    def on_button_revert_clicked(self):
 
664
        """Restore the source list from the startup of the dialog"""
 
665
 
 
666
        SoftwareProperties.revert(self)
 
667
        self.set_modified_sourceslist()
 
668
        self.show_auto_update_level()
 
669
        self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
 
670
        self.modified_sourceslist = False
 
671
 
 
672
    def set_modified_config(self):
 
673
        """The config was changed and now needs to be saved and reloaded"""
 
674
 
 
675
        SoftwareProperties.set_modified_config(self)
 
676
        self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
 
677
 
 
678
    def set_modified_sourceslist(self):
 
679
        """The sources list was changed and now needs to be saved and reloaded"""
 
680
 
 
681
        SoftwareProperties.set_modified_sourceslist(self)
 
682
        self.show_distro()
 
683
        self.show_isv_sources()
 
684
        self.show_cdrom_sources()
 
685
        self.userinterface.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
 
686
 
 
687
    def show_isv_sources(self):
 
688
        """ Show the repositories of independent software vendors in the
540
689
        third-party software tree view """
541
 
    self.isv_sources = self.get_isv_sources()[:]
542
 
    self.show_sources(self.isv_sources, self.userinterface.treeview_sources)
543
 
 
544
 
    if self.isv_sources < 1:
545
 
        self.userinterface.button_remove.setEnabled(False)
546
 
        self.userinterface.button_edit.setEnabled(False)
547
 
 
548
 
  def show_cdrom_sources(self):
549
 
    """ Show CD-ROM/DVD based repositories of the currently used distro in
 
690
 
 
691
        self.isv_sources = self.get_isv_sources()[:]
 
692
        self.show_sources(self.isv_sources,
 
693
                          self.userinterface.treeview_sources)
 
694
 
 
695
        if self.isv_sources < 1:
 
696
            self.userinterface.button_remove.setEnabled(False)
 
697
            self.userinterface.button_edit.setEnabled(False)
 
698
 
 
699
    def show_cdrom_sources(self):
 
700
        """ Show CD-ROM/DVD based repositories of the currently used distro in
550
701
        the CDROM based sources list """
551
 
    self.cdrom_sources = self.get_cdrom_sources()[:]
552
 
    self.show_sources(self.cdrom_sources, self.userinterface.treeview_cdroms)
553
 
 
554
 
  def show_sources(self, sources, treeview):
 
702
 
 
703
        self.cdrom_sources = self.get_cdrom_sources()[:]
 
704
        self.show_sources(self.cdrom_sources,
 
705
                          self.userinterface.treeview_cdroms)
 
706
 
 
707
    def show_sources(self, sources, treeview):
 
708
 
555
709
    # this workaround purposely replaces treeview.clear() (LP #102792)
556
 
    while treeview.topLevelItemCount() > 0:
557
 
      treeview.takeTopLevelItem(0)
558
 
 
559
 
    items = []
560
 
    for source in sources:
561
 
        contents = self.render_source(source)
562
 
        contents = contents.replace("<b>", "")
563
 
        contents = contents.replace("</b>", "")
564
 
        item = QTreeWidgetItem([utf8(contents)])
565
 
        if not source.disabled:
566
 
            item.setCheckState(0, Qt.Checked)
567
 
        else:
568
 
            item.setCheckState(0, Qt.Unchecked)
569
 
        items.append(item)
570
 
    treeview.addTopLevelItems(items)
571
 
 
572
 
  def show_keys(self):
573
 
    self.userinterface.treeview2.clear()
574
 
    for key in self.apt_key.list():
575
 
      self.userinterface.treeview2.addTopLevelItem(QTreeWidgetItem([utf8(key)]))
576
 
 
577
 
    if self.userinterface.treeview_sources.topLevelItemCount() < 1:
578
 
      self.userinterface.button_auth_remove.setEnabled(False)
579
 
 
580
 
  def on_combobox_update_interval_changed(self, index):
581
 
    #FIXME! move to backend
582
 
    if index != -1:
583
 
        value = self.combobox_interval_mapping[index]
 
710
 
 
711
        while treeview.topLevelItemCount() > 0:
 
712
            treeview.takeTopLevelItem(0)
 
713
 
 
714
        items = []
 
715
        for source in sources:
 
716
            contents = self.render_source(source)
 
717
            contents = contents.replace('<b>', '')
 
718
            contents = contents.replace('</b>', '')
 
719
            item = QTreeWidgetItem([utf8(contents)])
 
720
            if not source.disabled:
 
721
                item.setCheckState(0, Qt.Checked)
 
722
            else:
 
723
                item.setCheckState(0, Qt.Unchecked)
 
724
            items.append(item)
 
725
        treeview.addTopLevelItems(items)
 
726
 
 
727
    def show_keys(self):
 
728
        self.userinterface.treeview2.clear()
 
729
        for key in self.apt_key.list():
 
730
            self.userinterface.treeview2.addTopLevelItem(QTreeWidgetItem([utf8(key)]))
 
731
 
 
732
        if self.userinterface.treeview_sources.topLevelItemCount() < 1:
 
733
            self.userinterface.button_auth_remove.setEnabled(False)
 
734
 
 
735
    def on_combobox_update_interval_changed(self, index):
 
736
 
 
737
    # FIXME! move to backend
 
738
 
 
739
        if index != -1:
 
740
            value = self.combobox_interval_mapping[index]
 
741
 
584
742
        # Only write the key if it has changed
585
 
        if not value == apt_pkg.Config.FindI(softwareproperties.CONF_MAP["autoupdate"]):
586
 
            apt_pkg.Config.Set(softwareproperties.CONF_MAP["autoupdate"], str(value))
587
 
            self.write_config()
588
 
 
589
 
  def on_auto_update_toggled(self):
590
 
    """Enable or disable automatic updates and modify the user interface
 
743
 
 
744
            if not value \
 
745
                == apt_pkg.Config.FindI(softwareproperties.CONF_MAP['autoupdate'
 
746
                    ]):
 
747
                apt_pkg.Config.Set(softwareproperties.CONF_MAP['autoupdate'
 
748
                                   ], str(value))
 
749
                self.write_config()
 
750
 
 
751
    def on_auto_update_toggled(self):
 
752
        """Enable or disable automatic updates and modify the user interface
591
753
       accordingly"""
592
 
    if self.userinterface.checkbutton_auto_update.checkState() == Qt.Checked:
593
 
      self.userinterface.combobox_update_interval.setEnabled(True)
594
 
      self.userinterface.radiobutton_updates_inst_sec.setEnabled(True)
595
 
      self.userinterface.radiobutton_updates_download.setEnabled(True)
596
 
      self.userinterface.radiobutton_updates_notify.setEnabled(True)
 
754
 
 
755
        if self.userinterface.checkbutton_auto_update.checkState() \
 
756
            == Qt.Checked:
 
757
            self.userinterface.combobox_update_interval.setEnabled(True)
 
758
            self.userinterface.radiobutton_updates_inst_sec.setEnabled(True)
 
759
            self.userinterface.radiobutton_updates_download.setEnabled(True)
 
760
            self.userinterface.radiobutton_updates_notify.setEnabled(True)
 
761
 
597
762
      # if no frequency was specified use daily
598
 
      i = self.userinterface.combobox_update_interval.currentIndex()
599
 
      if i == -1:
600
 
          i = 0
601
 
          self.userinterface.combobox_update_interval.setCurrentIndex(i)
602
 
      value = self.combobox_interval_mapping[i]
603
 
    else:
604
 
      self.userinterface.combobox_update_interval.setEnabled(False)
605
 
      self.userinterface.radiobutton_updates_inst_sec.setEnabled(False)
606
 
      self.userinterface.radiobutton_updates_download.setEnabled(False)
607
 
      self.userinterface.radiobutton_updates_notify.setEnabled(False)
608
 
      SoftwareProperties.set_update_automation_level(self, None)
609
 
      value = 0
610
 
    self.set_update_interval(str(value))
611
 
 
612
 
  def on_add_clicked(self):
613
 
    """Show a dialog that allows to enter the apt line of a to be used repo"""
614
 
    dialog = DialogAdd(self.userinterface, self.sourceslist,
615
 
                       self.datadir, self.distro)
616
 
    line = dialog.run()
617
 
    if line != None:
618
 
      self.add_source_from_line(utf8(line))
619
 
      self.set_modified_sourceslist()
620
 
 
621
 
  def on_edit_clicked(self):
622
 
    """Show a dialog to edit an ISV source"""
623
 
    item = self.userinterface.treeview_sources.currentItem()
624
 
    if item is not None:
625
 
        index = self.userinterface.treeview_sources.indexOfTopLevelItem(item)
626
 
        dialogue = DialogEdit(self.userinterface, self.sourceslist, self.isv_sources[index], self.datadir)
627
 
        result = dialogue.run()
628
 
        if result == QDialog.Accepted:
 
763
 
 
764
            i = \
 
765
                self.userinterface.combobox_update_interval.currentIndex()
 
766
            if i == -1:
 
767
                i = 0
 
768
                self.userinterface.combobox_update_interval.setCurrentIndex(i)
 
769
            value = self.combobox_interval_mapping[i]
 
770
        else:
 
771
            self.userinterface.combobox_update_interval.setEnabled(False)
 
772
            self.userinterface.radiobutton_updates_inst_sec.setEnabled(False)
 
773
            self.userinterface.radiobutton_updates_download.setEnabled(False)
 
774
            self.userinterface.radiobutton_updates_notify.setEnabled(False)
 
775
            SoftwareProperties.set_update_automation_level(self, None)
 
776
            value = 0
 
777
        self.set_update_interval(str(value))
 
778
 
 
779
    def on_add_clicked(self):
 
780
        """Show a dialog that allows to enter the apt line of a to be used repo"""
 
781
 
 
782
        dialog = DialogAdd(self.userinterface, self.sourceslist,
 
783
                           self.datadir, self.distro)
 
784
        line = dialog.run()
 
785
        if line != None:
 
786
            self.add_source_from_line(utf8(line))
629
787
            self.set_modified_sourceslist()
630
 
            self.show_isv_sources()
 
788
 
 
789
    def on_edit_clicked(self):
 
790
        """Show a dialog to edit an ISV source"""
 
791
 
 
792
        item = self.userinterface.treeview_sources.currentItem()
 
793
        if item is not None:
 
794
            index = \
 
795
                self.userinterface.treeview_sources.indexOfTopLevelItem(item)
 
796
            dialogue = DialogEdit(self.userinterface, self.sourceslist,
 
797
                                  self.isv_sources[index], self.datadir)
 
798
            result = dialogue.run()
 
799
            if result == QDialog.Accepted:
 
800
                self.set_modified_sourceslist()
 
801
                self.show_isv_sources()
631
802
 
632
803
  # FIXME:outstanding from merge
633
 
  def on_isv_source_activated(self, treeview, path, column):
634
 
     """Open the edit dialog if a channel was double clicked"""
635
 
     ##FIXME TODO
 
804
 
 
805
    def on_isv_source_activated(
 
806
        self,
 
807
        treeview,
 
808
        path,
 
809
        column,
 
810
        ):
 
811
        """Open the edit dialog if a channel was double clicked"""
 
812
 
 
813
     # #FIXME TODO
636
814
     # check if the channel can be edited
637
 
     if self.button_edit.get_property("sensitive") == True:
638
 
         self.on_edit_clicked(treeview)
639
 
 
640
 
  def on_remove_clicked(self):
641
 
    """Remove the selected source"""
642
 
    item = self.userinterface.treeview_sources.currentItem()
643
 
    if item is not None:
644
 
        index = self.userinterface.treeview_sources.indexOfTopLevelItem(item)
645
 
        self.remove_source(self.isv_sources[index])
646
 
        self.show_isv_sources()
647
 
 
648
 
  def add_key_clicked(self):
649
 
    """Provide a file chooser that allows to add the gnupg of a trusted
 
815
 
 
816
        if self.button_edit.get_property('sensitive') == True:
 
817
            self.on_edit_clicked(treeview)
 
818
 
 
819
    def on_remove_clicked(self):
 
820
        """Remove the selected source"""
 
821
 
 
822
        item = self.userinterface.treeview_sources.currentItem()
 
823
        if item is not None:
 
824
            index = \
 
825
                self.userinterface.treeview_sources.indexOfTopLevelItem(item)
 
826
            self.remove_source(self.isv_sources[index])
 
827
            self.show_isv_sources()
 
828
 
 
829
    def add_key_clicked(self):
 
830
        """Provide a file chooser that allows to add the gnupg of a trusted
650
831
       software vendor"""
651
 
    home = QDir.homePath()
652
 
    if "SUDO_USER" in os.environ:
653
 
        home = os.path.expanduser("~%s" % os.environ["SUDO_USER"])
654
 
    url = KUrl.fromPath(home)
655
 
    filename = KFileDialog.getOpenFileName(url, 'application/pgp-keys', self.userinterface, utf8(_("Import key")))
656
 
    if filename:
657
 
      if not self.add_key(filename):
658
 
        title = _("Error importing selected file")
659
 
        text = _("The selected file may not be a GPG key file " \
660
 
                "or it might be corrupt.")
661
 
        KMessageBox.sorry(self.userinterface,
662
 
              utf8(text),
663
 
              utf8(title))
664
 
      self.show_keys()
665
 
 
666
 
  def remove_key_clicked(self):
667
 
    """Remove a trusted software vendor key"""
668
 
    item = self.userinterface.treeview2.currentItem()
669
 
    if item == None:
670
 
        return
671
 
    key = item.text(0)
672
 
    if not self.remove_key(key[:8]):
673
 
      title = _("Error removing the key")
674
 
      text = _("The key you selected could not be removed. "
675
 
               "Please report this as a bug.")
676
 
      KMessageBox.sorry(self.userinterface, utf8(text), utf8(title))
677
 
    self.show_keys()
678
 
 
679
 
  def on_restore_clicked(self):
680
 
    """Restore the original keys"""
681
 
    self.apt_key.update()
682
 
    self.show_keys()
683
 
 
684
 
  def on_close_button(self):
685
 
    """Show a dialog that a reload of the channel information is required
 
832
 
 
833
        home = QDir.homePath()
 
834
        if 'SUDO_USER' in os.environ:
 
835
            home = os.path.expanduser('~%s' % os.environ['SUDO_USER'])
 
836
        url = KUrl.fromPath(home)
 
837
        filename = KFileDialog.getOpenFileName(url,
 
838
                'application/pgp-keys', self.userinterface,
 
839
                utf8(_('Import key')))
 
840
        if filename:
 
841
            if not self.add_key(filename):
 
842
                title = _('Error importing selected file')
 
843
                text = \
 
844
                    _('The selected file may not be a GPG key file or it might be corrupt.'
 
845
                      )
 
846
                KMessageBox.sorry(self.userinterface, utf8(text),
 
847
                                  utf8(title))
 
848
            self.show_keys()
 
849
 
 
850
    def remove_key_clicked(self):
 
851
        """Remove a trusted software vendor key"""
 
852
 
 
853
        item = self.userinterface.treeview2.currentItem()
 
854
        if item == None:
 
855
            return
 
856
        key = item.text(0)
 
857
        if not self.remove_key(key[:8]):
 
858
            title = _('Error removing the key')
 
859
            text = \
 
860
                _('The key you selected could not be removed. Please report this as a bug.'
 
861
                  )
 
862
            KMessageBox.sorry(self.userinterface, utf8(text),
 
863
                              utf8(title))
 
864
        self.show_keys()
 
865
 
 
866
    def on_restore_clicked(self):
 
867
        """Restore the original keys"""
 
868
 
 
869
        self.apt_key.update()
 
870
        self.show_keys()
 
871
 
 
872
    def on_close_button(self):
 
873
        """Show a dialog that a reload of the channel information is required
686
874
       only if there is no parent defined"""
687
 
    if self.modified_sourceslist == True and self.options.no_update == False:
688
 
        messageBox = QMessageBox(self.userinterface)
689
 
        messageBox.setIcon(QMessageBox.Information)
690
 
        reloadButton = messageBox.addButton(utf8(_("Reload")), QMessageBox.AcceptRole)
691
 
        messageBox.addButton(QMessageBox.Close)
692
 
        text = _("<b><big>The information about available software is out-of-date</big></b>\n"
693
 
               "\n"
694
 
               "To install software and updates from newly added or changed sources, you "
695
 
               "have to reload the information about available software.\n"
696
 
               "\n"
697
 
               "You need a working internet connection to continue.")
698
 
        text = text.replace("\n", "<br />")
699
 
        messageBox.setText(utf8(text))
700
 
        messageBox.exec_()
701
 
        if (messageBox.clickedButton() == reloadButton):
702
 
                cmd = ["/usr/bin/qapt-batch", "--update"]
 
875
 
 
876
        if self.modified_sourceslist == True and self.options.no_update \
 
877
            == False:
 
878
            messageBox = QMessageBox(self.userinterface)
 
879
            messageBox.setIcon(QMessageBox.Information)
 
880
            reloadButton = messageBox.addButton(utf8(_('Reload')),
 
881
                    QMessageBox.AcceptRole)
 
882
            messageBox.addButton(QMessageBox.Close)
 
883
            text = \
 
884
                _('''<b><big>The information about available software is out-of-date</big></b>
 
885
 
 
886
To install software and updates from newly added or changed sources, you have to reload the information about available software.
 
887
 
 
888
You need a working internet connection to continue.''')
 
889
 
 
890
            text = text.replace('\n', '<br />')
 
891
            messageBox.setText(utf8(text))
 
892
            messageBox.exec_()
 
893
            if messageBox.clickedButton() == reloadButton:
 
894
                cmd = ['/usr/bin/qapt-batch', '--update']
703
895
                subprocess.call(cmd)
704
 
    kapp.quit()
 
896
        kapp.quit()
705
897
 
706
 
  def on_button_add_cdrom_clicked(self):
707
 
    '''Show a dialog that allows to add a repository located on a CDROM
 
898
    def on_button_add_cdrom_clicked(self):
 
899
        '''Show a dialog that allows to add a repository located on a CDROM
708
900
       or DVD'''
 
901
 
709
902
    # testing
710
 
    #apt_pkg.Config.Set("APT::CDROM::Rename","true")
711
 
 
712
 
    saved_entry = apt_pkg.Config.Find("Dir::Etc::sourcelist")
713
 
    tmp = tempfile.NamedTemporaryFile()
714
 
    apt_pkg.Config.Set("Dir::Etc::sourcelist",tmp.name)
715
 
    progress = CdromProgress(self.datadir, self, kapp)
716
 
    cdrom = apt_pkg.GetCdrom()
 
903
    # apt_pkg.Config.Set("APT::CDROM::Rename","true")
 
904
 
 
905
        saved_entry = apt_pkg.Config.Find('Dir::Etc::sourcelist')
 
906
        tmp = tempfile.NamedTemporaryFile()
 
907
        apt_pkg.Config.Set('Dir::Etc::sourcelist', tmp.name)
 
908
        progress = CdromProgress(self.datadir, self, kapp)
 
909
        cdrom = apt_pkg.GetCdrom()
 
910
 
717
911
    # if nothing was found just return
718
 
    try:
719
 
      res = cdrom.Add(progress)
720
 
    except SystemError, msg:
721
 
      title = _("CD Error")
722
 
      text = _("<big><b>Error scanning the CD</b></big>\n\n%s")%msg
723
 
      KMessageBox.sorry(self.userinterface, utf8(text), utf8(title))
724
 
      return
725
 
    finally:
726
 
      apt_pkg.Config.Set("Dir::Etc::sourcelist",saved_entry)
727
 
      progress.close()
728
 
 
729
 
    if res == False:
730
 
      return
 
912
 
 
913
        try:
 
914
            res = cdrom.Add(progress)
 
915
        except SystemError, msg:
 
916
            title = _('CD Error')
 
917
            text = _('''<big><b>Error scanning the CD</b></big>
 
918
 
 
919
%s''') \
 
920
                % msg
 
921
            KMessageBox.sorry(self.userinterface, utf8(text),
 
922
                              utf8(title))
 
923
            return
 
924
        finally:
 
925
            apt_pkg.Config.Set('Dir::Etc::sourcelist', saved_entry)
 
926
            progress.close()
 
927
 
 
928
        if res == False:
 
929
            return
 
930
 
731
931
    # read tmp file with source name (read only last line)
732
 
    line = ""
733
 
    for x in open(tmp.name):
734
 
      line = x
735
 
    if line != "":
736
 
      full_path = "%s%s" % (apt_pkg.Config.FindDir("Dir::Etc"),saved_entry)
 
932
 
 
933
        line = ''
 
934
        for x in open(tmp.name):
 
935
            line = x
 
936
        if line != '':
 
937
            full_path = '%s%s' % (apt_pkg.Config.FindDir('Dir::Etc'),
 
938
                                  saved_entry)
 
939
 
737
940
      # insert cdrom source first, so that it has precedence over network sources
738
 
      self.sourceslist.list.insert(0, SourceEntry(line,full_path))
739
 
      self.set_modified_sourceslist()
740
 
 
741
 
  def run(self):
742
 
    kapp.exec_()
 
941
 
 
942
            self.sourceslist.list.insert(0, SourceEntry(line,
 
943
                    full_path))
 
944
            self.set_modified_sourceslist()
 
945
 
 
946
    def run(self):
 
947
        kapp.exec_()
 
948
 
 
949