From 7a8c19cad48c76a68f2b4abc117a7377a15b4565 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 28 May 2008 11:23:37 +0100 Subject: [PATCH] Troubleshooter: split traceroute output into lines. Rather than escaping newline characters as part of the string, split the output into separate strings. --- ChangeLog | 6 ++++++ troubleshoot/CheckNetworkServerSanity.py | 3 ++- 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 36b5f90..ffea305 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-05-28 Tim Waugh + + * troubleshoot/CheckNetworkServerSanity.py + (CheckNetworkServerSanity.display): Split output lines from + traceroute. + 2008-05-27 Tim Waugh * configure.in: Version 1.0.0. diff --git a/troubleshoot/CheckNetworkServerSanity.py b/troubleshoot/CheckNetworkServerSanity.py index 6edc8f0..6db0edc 100644 --- a/troubleshoot/CheckNetworkServerSanity.py +++ b/troubleshoot/CheckNetworkServerSanity.py @@ -113,7 +113,8 @@ class CheckNetworkServerSanity(Question): stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = p.communicate () - self.answers['remote_server_traceroute'] = (stdout, stderr) + self.answers['remote_server_traceroute'] = (stdout.split ('\n'), + stderr.split ('\n')) except: # Problem executing command. pass -- 1.5.4.3 From ab4c850231cf4c4ca7b43f88d1f176e1633d5243 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 28 May 2008 12:49:25 +0100 Subject: [PATCH] Troubleshooter: prevent cupsd rotating logs while printing the test page. * troubleshoot/ErrorLogCheckpoint.py (ErrorLogCheckpoint.enable_clicked): Set MaxLogSize to 0 to avoid cupsd rotating the log while the test page is printed. * troubleshoot/ErrorLogFetch.py (ErrorLogFetch.button_clicked): Reset MaxLogSize. --- ChangeLog | 6 ++++++ troubleshoot/ErrorLogCheckpoint.py | 12 +++++++++--- troubleshoot/ErrorLogFetch.py | 29 ++++++++++++----------------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffea305..c191e1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-05-28 Tim Waugh + * troubleshoot/ErrorLogCheckpoint.py + (ErrorLogCheckpoint.enable_clicked): Set MaxLogSize to 0 to avoid + cupsd rotating the log while the test page is printed. + * troubleshoot/ErrorLogFetch.py (ErrorLogFetch.button_clicked): + Reset MaxLogSize. + * troubleshoot/CheckNetworkServerSanity.py (CheckNetworkServerSanity.display): Split output lines from traceroute. diff --git a/troubleshoot/ErrorLogCheckpoint.py b/troubleshoot/ErrorLogCheckpoint.py index ee3ee7f..5bd1e93 100644 --- a/troubleshoot/ErrorLogCheckpoint.py +++ b/troubleshoot/ErrorLogCheckpoint.py @@ -121,13 +121,19 @@ class ErrorLogCheckpoint(Question): return self.answers['cups_server_settings'] = settings.copy () + MAXLOGSIZE='MaxLogSize' try: - prev = int (settings[cups.CUPS_SERVER_DEBUG_LOGGING]) + prev_debug = int (settings[cups.CUPS_SERVER_DEBUG_LOGGING]) except KeyError: - prev = 0 + prev_debug = 0 + try: + prev_logsize = int (settings[MAXLOGSIZE]) + except KeyError: + prev_logsize = -1 - if prev == 0: + if prev_debug == 0 or prev_logsize != 0: settings[cups.CUPS_SERVER_DEBUG_LOGGING] = '1' + settings[MAXLOGSIZE] = '0' success = False try: debugprint ("Settings to set: " + repr (settings)) diff --git a/troubleshoot/ErrorLogFetch.py b/troubleshoot/ErrorLogFetch.py index aefd49e..7ac71fd 100644 --- a/troubleshoot/ErrorLogFetch.py +++ b/troubleshoot/ErrorLogFetch.py @@ -104,22 +104,17 @@ class ErrorLogFetch(Question): except cups.IPPError: return + settings[cups.CUPS_SERVER_DEBUG_LOGGING] = '0' + answers = self.troubleshooter.answers + orig_settings = answers['cups_server_settings'] + settings['MaxLogSize'] = orig_settings.get ('MaxLogSize', '2000000') + success = False try: - prev = int (settings[cups.CUPS_SERVER_DEBUG_LOGGING]) - except KeyError: - prev = 0 - - if prev != 0: - settings[cups.CUPS_SERVER_DEBUG_LOGGING] = '0' - success = False - try: - c.adminSetServerSettings (settings) - success = True - except cups.IPPError: - pass + c.adminSetServerSettings (settings) + success = True + except cups.IPPError: + pass - if success: - self.persistent_answers['error_log_debug_logging_unset'] = True - self.label.set_text (_("Debug logging disabled.")) - else: - self.label.set_text (_("Debug logging was already disabled.")) + if success: + self.persistent_answers['error_log_debug_logging_unset'] = True + self.label.set_text (_("Debug logging disabled.")) -- 1.5.4.3 From d82a6b6c444d61205fdb7a9cbb0bc19b626f582d Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 28 May 2008 13:14:49 +0100 Subject: [PATCH] Use gnulib's git-merge-changelog driver. --- .gitattributes | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e8495d5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +ChangeLog merge=merge-changelog -- 1.5.4.3 From 96c28cda5dbbe526f2e3546e2c45aec46b2d72d2 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 28 May 2008 15:22:13 +0100 Subject: [PATCH] Troubleshooter: Fetch device attributes for existing queue. * troubleshoot/DeviceListed.py (DeviceListed.collect_answer): Return all answers, including any set during the display method. (DeviceListed.display): Set cups_device_dict answer if the queue already exists, to make it easier to determine IEEE 1284 strings of devices that already have queues set up. * troubleshoot/DeviceListed.py (DeviceListed.display): Don't fetch devices if the selected queue is remote. --- ChangeLog | 8 ++++++++ troubleshoot/DeviceListed.py | 32 +++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index c191e1a..f8dd018 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-05-28 Tim Waugh + * troubleshoot/DeviceListed.py (DeviceListed.collect_answer): + Return all answers, including any set during the display method. + (DeviceListed.display): Set cups_device_dict answer if the queue + already exists, to make it easier to determine IEEE 1284 strings + of devices that already have queues set up. + * troubleshoot/DeviceListed.py (DeviceListed.display): Don't fetch + devices if the selected queue is remote. + * troubleshoot/ErrorLogCheckpoint.py (ErrorLogCheckpoint.enable_clicked): Set MaxLogSize to 0 to avoid cupsd rotating the log while the test page is printed. diff --git a/troubleshoot/DeviceListed.py b/troubleshoot/DeviceListed.py index 201d7f9..5b69bbb 100644 --- a/troubleshoot/DeviceListed.py +++ b/troubleshoot/DeviceListed.py @@ -55,10 +55,10 @@ class DeviceListed(Question): troubleshooter.new_page (page1, self) def display (self): + self.answers = {} answers = self.troubleshooter.answers - if answers['cups_queue_listed']: - return False - if answers['printer_is_remote']: + if (answers['printer_is_remote'] or + answers.get ('cups_printer_remote', False)): return False model = gtk.ListStore (gobject.TYPE_STRING, @@ -97,6 +97,17 @@ class DeviceListed(Question): except RuntimeError: pass + if answers['cups_queue_listed']: + try: + printer_dict = answers['cups_printer_dict'] + uri = printer_dict['device-uri'] + device = devices[uri] + self.answers['cups_device_dict'] = device + except KeyError: + pass + + return False + return True def connect_signals (self, handler): @@ -113,7 +124,7 @@ class DeviceListed(Question): def collect_answer (self): if not self.displayed: - return {} + return self.answers model, iter = self.treeview.get_selection ().get_selected () device = model.get_value (iter, 3) @@ -129,10 +140,13 @@ class DeviceListed(Question): if device: self.devices[uri] = device - return { 'cups_device_listed': False, - 'cups_devices_available': enum_devices (model).devices } + self.answers['cups_device_listed'] = False + avail = enum_devices (model).devices + self.answers['cups_devices_available'] = avail else: uri = model.get_value (iter, 2) - return { 'cups_device_listed': True, - 'cups_device_uri': uri, - 'cups_device_attributes': device } + self.answers['cups_device_listed'] = True + self.answers['cups_device_uri'] = uri + self.answers['cups_device_attributes'] = device + + return self.answers -- 1.5.4.3 From b92ec64d3b8e54742307a41ed0139582d8383cfc Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 28 May 2008 15:45:44 +0100 Subject: [PATCH] Fixed troubleshooter's cups_printer_remote data type. * troubleshoot/CheckPrinterSanity.py (CheckPrinterSanity.display): Make the cups_printer_remote answer a Boolean. --- ChangeLog | 3 +++ troubleshoot/CheckPrinterSanity.py | 2 +- 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8dd018..49da0a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2008-05-28 Tim Waugh + * troubleshoot/CheckPrinterSanity.py (CheckPrinterSanity.display): + Make the cups_printer_remote answer a Boolean. + * troubleshoot/DeviceListed.py (DeviceListed.collect_answer): Return all answers, including any set during the display method. (DeviceListed.display): Set cups_device_dict answer if the queue diff --git a/troubleshoot/CheckPrinterSanity.py b/troubleshoot/CheckPrinterSanity.py index 1df96f4..3bac5e6 100644 --- a/troubleshoot/CheckPrinterSanity.py +++ b/troubleshoot/CheckPrinterSanity.py @@ -111,7 +111,7 @@ class CheckPrinterSanity(Question): pass r = cups_printer_dict['printer-type'] & cups.CUPS_PRINTER_REMOTE - self.answers['cups_printer_remote'] = r + self.answers['cups_printer_remote'] = (r != 0) return False def collect_answer (self): -- 1.5.4.3 From be0e71703c40f240684dc50da0c74680067a204c Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 29 May 2008 10:14:53 +0100 Subject: [PATCH] Attempt Kerberos authentication for jobs requiring it. * jobviewer.py (JobViewer.update_job): If the job's auth-info-required attribute indicates Kerberos negotiation, try to authenticate the job without providing an auth-info attribute. --- ChangeLog | 6 ++++++ jobviewer.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49da0a0..ec08095 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-05-29 Tim Waugh + + * jobviewer.py (JobViewer.update_job): If the job's + auth-info-required attribute indicates Kerberos negotiation, try + to authenticate the job without providing an auth-info attribute. + 2008-05-28 Tim Waugh * troubleshoot/CheckPrinterSanity.py (CheckPrinterSanity.display): diff --git a/jobviewer.py b/jobviewer.py index 77b74a7..4fe4443 100644 --- a/jobviewer.py +++ b/jobviewer.py @@ -435,6 +435,21 @@ class JobViewer (monitor.Watcher): if not isinstance (auth_info_required, list): auth_info_required = [auth_info_required] + + if auth_info_required == ['negotiate']: + # Try Kerberos authentication. + try: + debugprint ("Trying Kerberos auth for job %d" % jobid) + c.authenticateJob (jobid) + except TypeError: + # Requires pycups-1.9.39 for optional auth parameter. + # Treat this as a normal job error. + debugprint ("... need newer pycups for that") + return + except cups.IPPError, (e, m): + self.show_IPP_Error (e, m) + return + dialog = authconn.AuthDialog (auth_info_required=auth_info_required) dialog.set_prompt (_("Authentication required for " "printing document `%s' (job %d)") % -- 1.5.4.3 From db7c5e1d5a6e6f8fbc07641996d56ac90f53577c Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 29 May 2008 11:12:08 +0100 Subject: [PATCH] Troubleshooter: Mark all jobs as test jobs by default. * troubleshoot/PrintTestPage.py (PrintTestPage.update_jobs_list): Mark jobs as test jobs by default so that people who don't realise they need to click the check-box still get sufficient information in the troubleshoot.txt file. --- ChangeLog | 5 +++++ troubleshoot/PrintTestPage.py | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec08095..836662c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-05-29 Tim Waugh + * troubleshoot/PrintTestPage.py (PrintTestPage.update_jobs_list): + Mark jobs as test jobs by default so that people who don't realise + they need to click the check-box still get sufficient information + in the troubleshoot.txt file. + * jobviewer.py (JobViewer.update_job): If the job's auth-info-required attribute indicates Kerberos negotiation, try to authenticate the job without providing an auth-info attribute. diff --git a/troubleshoot/PrintTestPage.py b/troubleshoot/PrintTestPage.py index 3b9f17f..3bb90f0 100644 --- a/troubleshoot/PrintTestPage.py +++ b/troubleshoot/PrintTestPage.py @@ -370,7 +370,7 @@ class PrintTestPage(Question): event['printer-name'] == queue): iter = model.append (None) self.job_to_iter[job] = iter - model.set_value (iter, 0, job in test_jobs) + model.set_value (iter, 0, True) model.set_value (iter, 1, job) else: continue -- 1.5.4.3 From 5210062cc31ae669bd461dd68dae4d1a5dff9802 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 29 May 2008 13:08:30 +0100 Subject: [PATCH] Pop up a menu when the Menu button is pressed. * system-config-printer.py (GUI.__init__): Connect IconView's popup-menu signal to... (GUI.dests_iconview_popup_menu): ...this new signal handler. * contextmenu.py (PrinterContextMenu.popup): Allow event to be None, for the case of the gtk.Widget popup-menu signal. --- ChangeLog | 6 ++++++ contextmenu.py | 14 +++++++++++--- system-config-printer.py | 6 ++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 836662c..db79ab9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-05-29 Tim Waugh + * system-config-printer.py (GUI.__init__): Connect IconView's + popup-menu signal to... + (GUI.dests_iconview_popup_menu): ...this new signal handler. + * contextmenu.py (PrinterContextMenu.popup): Allow event to be + None, for the case of the gtk.Widget popup-menu signal. + * troubleshoot/PrintTestPage.py (PrintTestPage.update_jobs_list): Mark jobs as test jobs by default so that people who don't realise they need to click the check-box still get sufficient information diff --git a/contextmenu.py b/contextmenu.py index 8d2c548..5c9fcc0 100644 --- a/contextmenu.py +++ b/contextmenu.py @@ -20,6 +20,8 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +import gtk.gdk + import cups import errordialogs import jobviewer @@ -106,9 +108,15 @@ class PrinterContextMenu: # Actions that require more than one destination show_widget (self.printer_context_create_class, n > 1) - self.printer_context_menu.popup (None, None, None, - event.button, - event.get_time (), None) + if event == None: + event_button = 0 + event_time = gtk.gdk.Event (gtk.gdk.NOTHING).get_time () + else: + event_button = event.button + event_time = event.get_time () + + self.printer_context_menu.popup (None, None, None, event_button, + event_time, None) ### Edit def on_printer_context_edit_activate (self, menuitem): diff --git a/system-config-printer.py b/system-config-printer.py index 3ee4b92..4a9f0f6 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -336,6 +336,8 @@ class GUI(GtkGUI, monitor.Watcher): self.dests_iconview_selection_changed) self.dests_iconview.connect ('button_release_event', self.dests_iconview_button_release_event) + self.dests_iconview.connect ('popup-menu', + self.dests_iconview_popup_menu) self.dests_iconview_selection_changed (self.dests_iconview) # setup some lists @@ -592,6 +594,10 @@ class GUI(GtkGUI, monitor.Watcher): self.enable.set_sensitive(n > 0 and any_disabled and not any_discovered) self.delete.set_sensitive(n > 0 and not any_discovered) + def dests_iconview_popup_menu (self, iconview): + paths = iconview.get_selected_items () + self.printer_context_menu.popup (None, iconview, paths) + def dests_iconview_button_release_event (self, iconview, event): if event.button > 1: click_path = iconview.get_path_at_pos (int (event.x), -- 1.5.4.3 From 552eeae8dac658ee38e553ec0de6f48863432183 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 29 May 2008 17:35:06 +0100 Subject: [PATCH] Fixed --configure-printer option. * system-config-printer.py (GUI.__init__): Renamed start_printer argument to configure_printer. Activate the relevant item. (GUI.populateList): No longer needs start_printer argument. (GUI.connect): Likewise. (GUI.on_connect_activate): Don't give start_printer argument to new thread. (GUI.on_copy_activate): Omit start_printer argument. (NewPrinterGUI.on_btnNPApply_clicked): Likewise. (main): Renamed start_printer argument to configure_printer. --- ChangeLog | 10 ++++++++++ system-config-printer.py | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index db79ab9..a069ae6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2008-05-29 Tim Waugh + * system-config-printer.py (GUI.__init__): Renamed start_printer + argument to configure_printer. Activate the relevant item. + (GUI.populateList): No longer needs start_printer argument. + (GUI.connect): Likewise. + (GUI.on_connect_activate): Don't give start_printer argument to + new thread. + (GUI.on_copy_activate): Omit start_printer argument. + (NewPrinterGUI.on_btnNPApply_clicked): Likewise. + (main): Renamed start_printer argument to configure_printer. + * system-config-printer.py (GUI.__init__): Connect IconView's popup-menu signal to... (GUI.dests_iconview_popup_menu): ...this new signal handler. diff --git a/system-config-printer.py b/system-config-printer.py index 4a9f0f6..99b1e59 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -149,7 +149,7 @@ class GtkGUI: class GUI(GtkGUI, monitor.Watcher): - def __init__(self, start_printer = None, change_ppd = False): + def __init__(self, configure_printer = None, change_ppd = False): try: self.language = locale.getlocale(locale.LC_MESSAGES) @@ -515,7 +515,7 @@ class GUI(GtkGUI, monitor.Watcher): self.monitor = monitor.Monitor (self, monitor_jobs=False) try: - self.populateList(start_printer, change_ppd) + self.populateList(change_ppd) except cups.HTTPError, (s,): self.cups = None self.setConnected() @@ -534,6 +534,18 @@ class GUI(GtkGUI, monitor.Watcher): except: nonfatalException () + if configure_printer: + # Need to find the entry in the iconview model and activate it. + model = self.dests_iconview.get_model () + iter = model.get_iter_first () + while iter != None: + name = model.get_value (iter, 2) + if name == configure_printer: + path = model.get_path (iter) + self.dests_iconview.item_activated (path) + break + iter = model.iter_next (iter) + def dests_iconview_item_activated (self, iconview, path): model = iconview.get_model () iter = model.get_iter (path) @@ -690,8 +702,7 @@ class GUI(GtkGUI, monitor.Watcher): known_servers.sort() return known_servers - def populateList(self, start_printer=None, change_ppd=False, - prompt_allowed=True): + def populateList(self, change_ppd=False, prompt_allowed=True): select_path = None if self.cups: @@ -843,12 +854,8 @@ class GUI(GtkGUI, monitor.Watcher): cups.setUser('') self.connect_user = cups.getUser() # Now start a new thread for connection. - args = [] - if self.printer: - args = [self.printer.name] - args.append (self.MainWindow) - args = tuple (args) - self.connect_thread = thread.start_new_thread(self.connect, args) + self.connect_thread = thread.start_new_thread(self.connect, + (self.MainWindow,)) def on_cancel_connect_clicked(self, widget): """ @@ -859,7 +866,7 @@ class GUI(GtkGUI, monitor.Watcher): self.connect_thread = None self.ConnectingDialog.hide() - def connect(self, start_printer=None, parent=None): + def connect(self, parent=None): """ Open a connection to a new server. Is executed in a separate thread! """ @@ -908,7 +915,7 @@ class GUI(GtkGUI, monitor.Watcher): self.ConnectingDialog.hide() self.cups = connection self.setConnected() - self.populateList(start_printer=start_printer) + self.populateList() except cups.HTTPError, (s,): self.cups = None self.setConnected() @@ -2023,7 +2030,7 @@ class GUI(GtkGUI, monitor.Watcher): pass self.copy_printer (self.entCopyName.get_text ()) - self.populateList(start_printer=self.printer.name) + self.populateList() def on_entCopyName_changed(self, widget): # restrict @@ -4639,7 +4646,7 @@ class NewPrinterGUI(GtkGUI): checkppd = ppd self.NewPrinterWindow.hide() - self.mainapp.populateList(start_printer=name) + self.mainapp.populateList() self.mainapp.fillPrinterTab (name) if check: try: @@ -4733,11 +4740,11 @@ class NewPrinterGUI(GtkGUI): self.MainWindow) -def main(start_printer = None, change_ppd = False): +def main(configure_printer = None, change_ppd = False): cups.setUser (os.environ.get ("CUPS_USER", cups.getUser())) gtk.gdk.threads_init() - mainwindow = GUI(start_printer, change_ppd) + mainwindow = GUI(configure_printer, change_ppd) if gtk.__dict__.has_key("main"): gtk.main() else: @@ -4755,16 +4762,16 @@ if __name__ == "__main__": show_help () sys.exit (1) - start_printer = None + configure_printer = None change_ppd = False for opt, optarg in opts: if (opt == "--configure-printer" or opt == "--choose-driver"): - start_printer = optarg + configure_printer = optarg if opt == "--choose-driver": change_ppd = True elif opt == '--debug': set_debugging (True) - main(start_printer, change_ppd) + main(configure_printer, change_ppd) -- 1.5.4.3 From de78cf67c32b57d2a3ddf2cfcaa4098a5176cfc5 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Fri, 30 May 2008 11:06:24 +0100 Subject: [PATCH] Fixed --change-ppd option. * system-config-printer.py (GUI.populateList): No longer needs change_ppd argument. (GUI.__init__): Don't give change_ppd argument to populateList. (GUI.printer_properties_response): New method. (GUI.__init__): Connect the response signal to it. (GUI.dests_iconview_item_activated): Just show the dialog, don't call its run method. (GUI.__init__): Click the Change PPD... button if the change_ppd argument was given. --- ChangeLog | 12 ++++++++++++ system-config-printer.py | 27 +++++++++++++-------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index a069ae6..8e85188 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-05-30 Tim Waugh + + * system-config-printer.py (GUI.populateList): No longer needs + change_ppd argument. + (GUI.__init__): Don't give change_ppd argument to populateList. + (GUI.printer_properties_response): New method. + (GUI.__init__): Connect the response signal to it. + (GUI.dests_iconview_item_activated): Just show the dialog, don't + call its run method. + (GUI.__init__): Click the Change PPD... button if the change_ppd + argument was given. + 2008-05-29 Tim Waugh * system-config-printer.py (GUI.__init__): Renamed start_printer diff --git a/system-config-printer.py b/system-config-printer.py index 99b1e59..61c15b5 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -370,6 +370,10 @@ class GUI(GtkGUI, monitor.Watcher): self.xml.signal_autoconnect(self) + # Printer Properties dialog + self.PrinterPropertiesDialog.connect ('response', + self.printer_properties_response) + # Printer Properties tree view col = gtk.TreeViewColumn ('', gtk.CellRendererText (), markup=0) self.tvPrinterProperties.append_column (col) @@ -515,7 +519,7 @@ class GUI(GtkGUI, monitor.Watcher): self.monitor = monitor.Monitor (self, monitor_jobs=False) try: - self.populateList(change_ppd) + self.populateList() except cups.HTTPError, (s,): self.cups = None self.setConnected() @@ -543,6 +547,8 @@ class GUI(GtkGUI, monitor.Watcher): if name == configure_printer: path = model.get_path (iter) self.dests_iconview.item_activated (path) + if change_ppd: + self.btnChangePPD.clicked () break iter = model.iter_next (iter) @@ -567,16 +573,12 @@ class GUI(GtkGUI, monitor.Watcher): host = CUPS_server_hostname () self.PrinterPropertiesDialog.set_title (_("Printer Properties - " "`%s' on %s") % (name, host)) - finished = False - while not finished: - response = self.PrinterPropertiesDialog.run () - if response == gtk.RESPONSE_OK: - if not self.save_printer (self.printer): - finished = True - else: - finished = True + self.PrinterPropertiesDialog.show () - self.PrinterPropertiesDialog.hide () + def printer_properties_response (self, dialog, response): + if (response != gtk.RESPONSE_OK or + not self.save_printer (self.printer)): + dialog.hide () def dests_iconview_selection_changed (self, iconview): paths = iconview.get_selected_items () @@ -702,7 +704,7 @@ class GUI(GtkGUI, monitor.Watcher): known_servers.sort() return known_servers - def populateList(self, change_ppd=False, prompt_allowed=True): + def populateList(self, prompt_allowed=True): select_path = None if self.cups: @@ -803,9 +805,6 @@ class GUI(GtkGUI, monitor.Watcher): self.mainlist.append (row=[object, pixbuf, name, tip]) - if change_ppd: - self.on_btnChangePPD_clicked (self.btnChangePPD) - # Connect to Server def on_connect_servername_changed(self, widget): -- 1.5.4.3 From e2e92942ab50f336a9894c60b3fb807f6a8f5af0 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Fri, 30 May 2008 13:11:04 +0100 Subject: [PATCH] Removed gladep file. --- system-config-printer.gladep | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-) delete mode 100644 system-config-printer.gladep diff --git a/system-config-printer.gladep b/system-config-printer.gladep deleted file mode 100644 index 15b7e09..0000000 --- a/system-config-printer.gladep +++ /dev/null @@ -1,8 +0,0 @@ - - - - - System-config-printer - system-config-printer - FALSE - -- 1.5.4.3 From 4b16be7cae529e8d40e8b1d69a1def1430274de7 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Fri, 30 May 2008 13:11:33 +0100 Subject: [PATCH] Added .gitignore file. --- .gitignore | 34 ++++++++++++++++++++++++++++++++++ 1 files changed, 34 insertions(+), 0 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af4edfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +Makefile.in +Makefile +configure +config.status +config.log +autom4te.cache +missing +INSTALL + +intltool-extract* +intltool-merge* +intltool-update* + +*.pyc +*.gladep + +po/*.mo +po/POTFILES +po/Makefile.in +po/Makefile +po/stamp-it + +# These are generated from *.in files +config.py +my-default-printer +system-config-printer +system-config-printer-applet + +# Backup files +*.bak +*~ + +# Tarballs +system-config-printer-*.tar.?z* -- 1.5.4.3 From e4b614bdf88bd75080b8f4b3b801a63be67874e0 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Fri, 30 May 2008 14:42:58 +0100 Subject: [PATCH] Troubleshooter: Check USB permissions. * troubleshoot/CheckUSBPermissions.py: New module. * troubleshoot/__init__.py (QUESTIONS): Run it. * Makefile.am (nobase_pkgdata_DATA): Ship it. --- ChangeLog | 6 ++ Makefile.am | 1 + troubleshoot/CheckUSBPermissions.py | 158 +++++++++++++++++++++++++++++++++++ troubleshoot/__init__.py | 2 + 4 files changed, 167 insertions(+), 0 deletions(-) create mode 100644 troubleshoot/CheckUSBPermissions.py diff --git a/ChangeLog b/ChangeLog index 8e85188..b3fc249 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-05-30 Tim Waugh + * troubleshoot/CheckUSBPermissions.py: New module. + * troubleshoot/__init__.py (QUESTIONS): Run it. + * Makefile.am (nobase_pkgdata_DATA): Ship it. + +2008-05-30 Tim Waugh + * system-config-printer.py (GUI.populateList): No longer needs change_ppd argument. (GUI.__init__): Don't give change_ppd argument to populateList. diff --git a/Makefile.am b/Makefile.am index 6029853..3fc370b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,7 @@ nobase_pkgdata_DATA= \ troubleshoot/CheckNetworkServerSanity.py \ troubleshoot/CheckPPDSanity.py \ troubleshoot/CheckPrinterSanity.py \ + troubleshoot/CheckUSBPermissions.py \ troubleshoot/ChooseNetworkPrinter.py \ troubleshoot/ChoosePrinter.py \ troubleshoot/DeviceListed.py \ diff --git a/troubleshoot/CheckUSBPermissions.py b/troubleshoot/CheckUSBPermissions.py new file mode 100644 index 0000000..5d5e3eb --- /dev/null +++ b/troubleshoot/CheckUSBPermissions.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +## Printing troubleshooter + +## Copyright (C) 2008 Red Hat, Inc. +## Copyright (C) 2008 Tim Waugh + +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import glob +import os +import subprocess +import urllib +from base import * +class CheckUSBPermissions(Question): + def __init__ (self, troubleshooter): + Question.__init__ (self, troubleshooter, "Check USB permissions") + troubleshooter.new_page (gtk.Label (), self) + + def display (self): + self.answers = {} + answers = self.troubleshooter.answers + if answers['cups_queue_listed']: + if answers['is_cups_class']: + return False + + cups_printer_dict = answers['cups_printer_dict'] + device_uri = cups_printer_dict['device-uri'] + elif answers.get ('cups_device_listed', False): + device_uri = answers['cups_device_uri'] + else: + return False + + (scheme, rest) = urllib.splittype (device_uri) + if scheme not in ['hp', 'hpfax', 'usb', 'hal']: + return False + + LSUSB = "/sbin/lsusb" + if not os.access (LSUSB, os.X_OK): + return False + + GETFACL = "/usr/bin/getfacl" + if not os.access (GETFACL, os.X_OK): + return False + + # Run lsusb + try: + lsusb = subprocess.Popen ("LC_ALL=C " + LSUSB + " -v", shell=True, + stdin=file("/dev/null"), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (lsusb_stdout, lsusb_stderr) = lsusb.communicate () + except: + # Problem executing command. + return False + + # Now parse it. + dev_by_id = {} + this_dev = None + for line in lsusb_stdout.split ('\n'): + if (this_dev != None and + ((line.find ("bInterfaceClass") != -1 and + line.find ("7 Printer") != -1) or + (line.find ("bInterfaceSubClass") != -1 and + line.find ("1 Printer") != -1))): + mfr = dev_by_id.get (this_mfr_id, {}) + mdl = mfr.get (this_mdl_id, []) + mdl.append (this_dev) + mfr[this_mdl_id] = mdl + dev_by_id[this_mfr_id] = mfr + this_dev = None + continue + + separators = [ ('Bus ', 3), + (' Device ', 3), + (': ID ', 4), + (':', 4), + (' ', -1)] + fields = [] + i = 0 + p = line + while i < len (separators): + (sep, length) = separators[i] + if not p.startswith (sep): + break + start = len (sep) + if length == -1: + end = len (p) + fields.append (p[start:]) + else: + end = start + length + fields.append (p[start:end]) + + p = p[end:] + i += 1 + + if i < len (separators): + continue + + if not scheme.startswith ('hp') and fields[2] != '03f0': + # Skip non-HP printers if we know we're using HPLIP. + continue + + this_dev = { 'bus': fields[0], + 'dev': fields[1], + 'name': fields[4], + 'full': line } + this_mfr_id = fields[2] + this_mdl_id = fields[3] + + infos = {} + paths = [] + if not scheme.startswith ('hp'): + paths.extend (glob.glob ("/dev/usb/lp?")) + for mfr_id, mdls in dev_by_id.iteritems (): + for mdl_id, devs in mdls.iteritems (): + for dev in devs: + path = "/dev/bus/usb/%s/%s" % (dev['bus'], dev['dev']) + paths.append (path) + infos[path] = dev['full'] + + perms = [] + for path in paths: + try: + getfacl = subprocess.Popen ("LC_ALL=C %s %s" % (GETFACL, path), + shell=True, + stdin=file("/dev/null"), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (getfacl_stdout, getfacl_stderr) = getfacl.communicate () + output = filter (lambda x: len (x) > 0, + getfacl_stdout.split ('\n')) + except: + # Problem executing command. + output = [] + + info = infos.get (path, path) + perms.append ((info, output)) + + self.answers['getfacl_output'] = perms + + # Don't actually display anything, just collect information. + return False + + def collect_answer (self): + return self.answers diff --git a/troubleshoot/__init__.py b/troubleshoot/__init__.py index e33e5e5..b959a09 100644 --- a/troubleshoot/__init__.py +++ b/troubleshoot/__init__.py @@ -289,6 +289,8 @@ QUESTIONS = ["Welcome", "LocalOrRemote", "DeviceListed", + "CheckUSBPermissions", + "RemoteAddress", "CheckNetworkServerSanity", "ChooseNetworkPrinter", -- 1.5.4.3 From eba5512ed571063db8c96a11f292fe860b678047 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Fri, 30 May 2008 15:00:01 +0100 Subject: [PATCH] Don't try to ship deleted file. --- Makefile.am | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3fc370b..5facce0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,7 +121,6 @@ EXTRA_DIST=\ newprinternotification.conf \ bootstrap \ mkinstalldirs \ - system-config-printer.gladep \ system-config-printer.desktop.in \ manage-print-jobs.desktop.in \ my-default-printer.desktop.in \ -- 1.5.4.3 From 9270db3c3bb71d2307e7e1a031761f2fe71d8745 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Sat, 31 May 2008 10:25:17 +0100 Subject: [PATCH] Harden applet against races on start-up. * applet.py (WaitForJobs): Harden against races. (cherry picked from commit 906134b1778d0f3204dcdfcfcd0c02d46d665360) --- ChangeLog | 4 ++++ applet.py | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3fc249..9fc234f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-05-31 Tim Waugh + + * applet.py (WaitForJobs): Harden against races. + 2008-05-30 Tim Waugh * troubleshoot/CheckUSBPermissions.py: New module. diff --git a/applet.py b/applet.py index a149835..fc161d4 100644 --- a/applet.py +++ b/applet.py @@ -311,8 +311,9 @@ if __name__ == '__main__': DBUS_PATH="/com/redhat/PrinterSpooler" DBUS_IFACE="com.redhat.PrinterSpooler" - def __init__ (self, bus): + def __init__ (self, bus, waitloop): self.bus = bus + self.waitloop = waitloop self.timer = None bus.add_signal_receiver (self.handle_dbus_signal, path=self.DBUS_PATH, @@ -335,17 +336,14 @@ if __name__ == '__main__': debugprint ("checking for jobs") if any_jobs (): gobject.source_remove (self.timer) - try: - waitloop.quit () - except: - pass + self.waitloop.quit () # Don't run this timer again. return False ### - jobwaiter = WaitForJobs(bus) waitloop = gobject.MainLoop () + jobwaiter = WaitForJobs(bus, waitloop) waitloop.run() del jobwaiter waitloop = None -- 1.5.4.3 From e8c2f856f3639cfa75f516b3b11fe3aff6f8b05e Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Mon, 2 Jun 2008 14:28:27 +0100 Subject: [PATCH] Handle IPP_NOT_FOUND when fetching PPDs. * system-config-printer.py (NewPrinterGUI.init): Handle exceptions when fetching PPDs. (cherry picked from commit e43958c350adc79bf823510fd7712749e46efc71) --- ChangeLog | 5 +++++ system-config-printer.py | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9fc234f..7e2a7f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-06-02 Tim Waugh + + * system-config-printer.py (NewPrinterGUI.init): Handle exceptions + when fetching PPDs. + 2008-05-31 Tim Waugh * applet.py (WaitForJobs): Harden against races. diff --git a/system-config-printer.py b/system-config-printer.py index 61c15b5..9cf8438 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -2516,7 +2516,13 @@ class NewPrinterGUI(GtkGUI): self.NewPrinterWindow.set_title(_("Change Device URI")) self.ntbkNewPrinter.set_current_page(1) self.queryDevices () - self.loadPPDs() + + try: + self.loadPPDs() + except cups.IPPError, (e, m): + show_IPP_Error (e, m, parent=self.mainapp.MainWindow) + return + self.fillDeviceTab(self.mainapp.printer.device_uri) # Start fetching information from CUPS in the background self.new_printer_PPDs_loaded = False @@ -2555,7 +2561,12 @@ class NewPrinterGUI(GtkGUI): self.auto_make = 'Raw' self.auto_model = 'Queue' - self.loadPPDs () + try: + self.loadPPDs () + except cups.IPPError, (e, m): + show_IPP_Error (e, m, parent=self.mainapp.MainWindow) + return + self.fillMakeList() if self.dialog_mode in ("printer", "class"): -- 1.5.4.3 From 24d7ba139c70a77ea53b8decdad420d07bd673d1 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Mon, 2 Jun 2008 17:53:32 +0100 Subject: [PATCH] Don't display dialog when jobs get stopped due to printer pausing. * jobviewer.py (JobViewer.job_event): Ignore stopped jobs when they have been stopped due to the printer being paused. (cherry picked from commit 143616d19b8f1419696f96d49d0e27d05014e5ec) --- ChangeLog | 5 +++++ jobviewer.py | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e2a7f6..60789d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-06-02 Tim Waugh + * jobviewer.py (JobViewer.job_event): Ignore stopped jobs when + they have been stopped due to the printer being paused. + +2008-06-02 Tim Waugh + * system-config-printer.py (NewPrinterGUI.init): Handle exceptions when fetching PPDs. diff --git a/jobviewer.py b/jobviewer.py index 4fe4443..8d81882 100644 --- a/jobviewer.py +++ b/jobviewer.py @@ -857,10 +857,11 @@ class JobViewer (monitor.Watcher): except RuntimeError: pass + may_be_problem = True if (jobdata['job-state'] == cups.IPP_JOB_HELD and jobdata['job-hold-until'] == 'auth-info-required'): # Leave this to update_job to deal with. - pass + may_be_problem = False else: # Other than that, unfortunately the only # clue we get is the notify-text, which is not @@ -878,6 +879,11 @@ class JobViewer (monitor.Watcher): # error_log file for details." # # "Authentication is required for job %d." + # [This case is handled in the update_job method.] + # + # "Job stopped due to printer being paused" + # [This should be ignored, as the job was doing just + # fine until the printer was stopped for other reasons.] notify_text = event['notify-text'] document = jobdata['job-name'] if notify_text.find ("backend errors") != -1: @@ -886,12 +892,15 @@ class JobViewer (monitor.Watcher): elif notify_text.find ("filter errors") != -1: message = _("There was a problem processing document `%s' " "(job %d).") % (document, jobid) + elif notify_text.find ("being paused") != -1: + may_be_problem = False else: - # Give up and use the untranslated provided. + # Give up and use the provided message untranslated. message = _("There was a problem printing document `%s' " "(job %d): `%s'.") % (document, jobid, notify_text) + if may_be_problem: self.toggle_window_display (self.statusicon, force_show=True) dialog = gtk.Dialog (_("Print Error"), self.MainWindow, 0, (_("_Diagnose"), gtk.RESPONSE_NO, -- 1.5.4.3 From 8892e92f09da8b9d31fc7c0f2356883e2bb27c89 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Tue, 3 Jun 2008 10:42:45 +0100 Subject: [PATCH] Only show one stopped job dialog per job. * jobviewer.py (JobViewer.__init__): Initialise set of stopped job IDs for which we are showing a dialog. (JobViewer.job_event): Don't show stopped-job dialog if we are already showing one for this job. (JobViewer.job_event): Add job ID to set before showing dialog. (JobViewer.print_error_dialog_response): Remove job ID from set. (cherry picked from commit c70d01c2a329c0ea95f7652e8edc5cf08c2aea9b) --- ChangeLog | 9 +++++++++ jobviewer.py | 11 ++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60789d1..ded8c70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-03 Tim Waugh + + * jobviewer.py (JobViewer.__init__): Initialise set of stopped job + IDs for which we are showing a dialog. + (JobViewer.job_event): Don't show stopped-job dialog if we are + already showing one for this job. + (JobViewer.job_event): Add job ID to set before showing dialog. + (JobViewer.print_error_dialog_response): Remove job ID from set. + 2008-06-02 Tim Waugh * jobviewer.py (JobViewer.job_event): Ignore stopped jobs when diff --git a/jobviewer.py b/jobviewer.py index 8d81882..b9bf797 100644 --- a/jobviewer.py +++ b/jobviewer.py @@ -68,6 +68,7 @@ class JobViewer (monitor.Watcher): self.jobs = {} self.jobiters = {} self.active_jobs = set() # of job IDs + self.stopped_job_prompts = set() # of job IDs self.which_jobs = "not-completed" self.printer_state_reasons = {} self.num_jobs_when_hidden = 0 @@ -341,9 +342,10 @@ class JobViewer (monitor.Watcher): # Return code controls whether the timeout will recur. return need_update - def print_error_dialog_response(self, dialog, response): + def print_error_dialog_response(self, dialog, response, jobid): dialog.hide () dialog.destroy () + self.stopped_job_prompts.remove (jobid) if response == gtk.RESPONSE_NO: # Diagnose if not self.__dict__.has_key ('troubleshooter'): @@ -838,7 +840,8 @@ class JobViewer (monitor.Watcher): self.active_jobs.remove (jobid) # Look out for stopped jobs. - if self.trayicon and eventname == 'job-stopped': + if (self.trayicon and eventname == 'job-stopped' and + not jobid in self.stopped_job_prompts): # Why has the job stopped? It might be due to a job error # of some sort, or it might be that the backend requires # authentication. If the latter, the job will be held not @@ -936,7 +939,9 @@ class JobViewer (monitor.Watcher): vbox.pack_start (label, False, False, 0) hbox.pack_start (vbox, False, False, 0) dialog.vbox.pack_start (hbox) - dialog.connect ('response', self.print_error_dialog_response) + dialog.connect ('response', + self.print_error_dialog_response, jobid) + self.stopped_job_prompts.add (jobid) dialog.show_all () self.update_job (jobid, jobdata) -- 1.5.4.3 From e0bb09dfcfc723184c56afce887478fd4db32c92 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Tue, 3 Jun 2008 10:43:42 +0100 Subject: [PATCH] Allow 'make run-applet' for testing the applet. * Makefile.am (run-applet): New target. (cherry picked from commit 459246d724bba56d39acbf51884fd6ca886d5708) --- ChangeLog | 4 ++++ Makefile.am | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index ded8c70..a5a3aca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-06-03 Tim Waugh + * Makefile.am (run-applet): New target. + +2008-06-03 Tim Waugh + * jobviewer.py (JobViewer.__init__): Initialise set of stopped job IDs for which we are showing a dialog. (JobViewer.job_event): Don't show stopped-job dialog if we are diff --git a/Makefile.am b/Makefile.am index 5facce0..f4fc541 100644 --- a/Makefile.am +++ b/Makefile.am @@ -155,6 +155,10 @@ run: SYSTEM_CONFIG_PRINTER_GLADE=$(top_srcdir) \ python $(top_srcdir)/system-config-printer.py --debug +run-applet: + SYSTEM_CONFIG_PRINTER_GLADE=$(top_srcdir) \ + python $(top_srcdir)/applet.py --debug + help: @echo "Usage: make " @echo "Available targets:" -- 1.5.4.3 From b6dbb8d5f3df5f102db0acc6e60ae091e2ce13de Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Tue, 3 Jun 2008 16:18:39 +0100 Subject: [PATCH] Don't assume root for test page auth dialog (bug #449753). * system-config-printer.py (GUI.on_btnPrintTestPage_clicked): Don't automatically try authenticating as root if asked for a password when printing a test page, as the authentication is likely to be needed for the remote print server. * authconn.py (Connection.__init__): New optional parameter try_as_root. (Connection._perform_authentication): Only try as root if allowed to. (cherry picked from commit 1ff78de59e8c23fb22b465ff49a87f43feb8b1c4) --- ChangeLog | 12 ++++++++++++ authconn.py | 7 +++++-- system-config-printer.py | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5a3aca..38fc8b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2008-06-03 Tim Waugh + * system-config-printer.py (GUI.on_btnPrintTestPage_clicked): + Don't automatically try authenticating as root if asked for a + password when printing a test page, as the authentication is + likely to be needed for the remote print server. + + * authconn.py (Connection.__init__): New optional parameter + try_as_root. + (Connection._perform_authentication): Only try as root if allowed + to. + +2008-06-03 Tim Waugh + * Makefile.am (run-applet): New target. 2008-06-03 Tim Waugh diff --git a/authconn.py b/authconn.py index 0c98a0d..3d6ade2 100644 --- a/authconn.py +++ b/authconn.py @@ -93,9 +93,10 @@ class AuthDialog(gtk.Dialog): self.field_entry[i].grab_focus () class Connection: - def __init__ (self, parent=None): + def __init__ (self, parent=None, try_as_root=True): self._use_password = '' self._parent = parent + self._try_as_root = try_as_root self._connect () self._prompt_allowed = True @@ -185,7 +186,9 @@ class Connection: if self._passes == 2: # Tried the operation without a password and it failed. - if self._user != 'root' and self._server[0] == '/': + if (self._try_as_root and + self._user != 'root' and + self._server[0] == '/'): # This is a UNIX domain socket connection so we should # not have needed a password, and so the operation must # not be something that the current user is authorised to diff --git a/system-config-printer.py b/system-config-printer.py index 9cf8438..685777b 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -1417,7 +1417,7 @@ class GUI(GtkGUI, monitor.Watcher): # as a normal job. user = cups.getUser () cups.setUser ('') - c = authconn.Connection (self.MainWindow) + c = authconn.Connection (self.MainWindow, try_as_root=False) if custom_testpage and os.path.exists(custom_testpage): debugprint ('Printing custom test page ' + custom_testpage) job_id = c.printTestPage(self.printer.name, -- 1.5.4.3 From 373b0abf9872545ca7dee9a236f33711b6e6c47e Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Tue, 3 Jun 2008 17:12:26 +0100 Subject: [PATCH] Made printer properties dialog tab labels slightly wider. * system-config-printer.glade: Adjust left hpane width in the printer properties dialog to be slightly wider. (cherry picked from commit 213dabdfa14193cb0b8bee01f1498b56bc2dc72d) --- ChangeLog | 5 +++++ system-config-printer.glade | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38fc8b8..54ff986 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-06-03 Tim Waugh + * system-config-printer.glade: Adjust left hpane width in the + printer properties dialog to be slightly wider. + +2008-06-03 Tim Waugh + * system-config-printer.py (GUI.on_btnPrintTestPage_clicked): Don't automatically try authenticating as root if asked for a password when printing a test page, as the authentication is diff --git a/system-config-printer.glade b/system-config-printer.glade index 1ee987a..52b7713 100644 --- a/system-config-printer.glade +++ b/system-config-printer.glade @@ -6484,7 +6484,7 @@ Till Kamppeter <till.kamppeter@gmail.com> - 126 + 135 True True GTK_POLICY_AUTOMATIC -- 1.5.4.3 From df6ba562fa09d481ac8f2675aae04618faf75418 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 4 Jun 2008 09:08:36 +0100 Subject: [PATCH] Fixed 'install driver' dialog (bug #449860). * system-config-printer.py (GUI.__init__): Don't fetch InstallDialog widget here... (NewPrinterGUI.__init__): ...fetch it here instead (bug #449860). (NewPrinterGUI.checkDriverExists): Fixed traceback. (cherry picked from commit bc597966c98b27fabb55e4fc4f864f541d781a41) (cherry picked from commit cb6a6d423677cd8d1a1c765389d9c45814a76401) --- ChangeLog | 7 +++++++ system-config-printer.py | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54ff986..8ebe6f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-06-04 Tim Waugh + + * system-config-printer.py (GUI.__init__): Don't fetch + InstallDialog widget here... + (NewPrinterGUI.__init__): ...fetch it here instead (bug #449860). + (NewPrinterGUI.checkDriverExists): Fixed traceback. + 2008-06-03 Tim Waugh * system-config-printer.glade: Adjust left hpane width in the diff --git a/system-config-printer.py b/system-config-printer.py index 685777b..904d6fe 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -253,7 +253,6 @@ class GUI(GtkGUI, monitor.Watcher): "ConnectingDialog", "lblConnecting", "NewPrinterName", "entCopyName", "btnCopyOk", "InfoDialog", "lblInfo", - "InstallDialog", "lblInstall", "AboutDialog", "WaitWindow", "lblWait", ) @@ -2363,7 +2362,8 @@ class NewPrinterGUI(GtkGUI): "rbtnNPDownloadLicenseYes", "rbtnNPDownloadLicenseNo", "NewPrinterName", "entCopyName", "btnCopyOk", - "InfoDialog", "lblInfo") + "InfoDialog", "lblInfo", + "InstallDialog", "lblInstall") # share with mainapp self.WaitWindow = mainapp.WaitWindow self.lblWait = mainapp.lblWait @@ -4722,7 +4722,7 @@ class NewPrinterGUI(GtkGUI): (name, pkg)) dialog = self.InstallDialog self.lblInstall.set_markup(install_text) - dialog.set_transient_for (self.MainWindow) + dialog.set_transient_for (self.mainapp.MainWindow) response = dialog.run () dialog.hide () if response == gtk.RESPONSE_OK: @@ -4747,7 +4747,7 @@ class NewPrinterGUI(GtkGUI): "but it is not currently installed. " "Please install it before using this " "printer.") % (name, (exes + pkgs)[0]), - self.MainWindow) + self.mainapp.MainWindow) def main(configure_printer = None, change_ppd = False): -- 1.5.4.3 From 22c6f509fc43f896db83950c177d037b32237bd6 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 4 Jun 2008 11:00:18 +0100 Subject: [PATCH] Show tracebacks for unhandled exceptions in threads. * system-config-printer.py (GUI.connect): Always show traceback for unhandled exceptions if debugging. (NewPrinterGUI.getDevices_thread): Likewise. (cherry picked from commit d56fa2b0abe5be781b63e08f056679a7ea92fa3e) --- ChangeLog | 6 ++++++ system-config-printer.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8ebe6f7..ad38111 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-06-04 Tim Waugh + * system-config-printer.py (GUI.connect): Always show traceback + for unhandled exceptions if debugging. + (NewPrinterGUI.getDevices_thread): Likewise. + +2008-06-04 Tim Waugh + * system-config-printer.py (GUI.__init__): Don't fetch InstallDialog widget here... (NewPrinterGUI.__init__): ...fetch it here instead (bug #449860). diff --git a/system-config-printer.py b/system-config-printer.py index 904d6fe..aa2d46f 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -887,6 +887,8 @@ class GUI(GtkGUI, monitor.Watcher): except RuntimeError: # When we connect, avoid the domain socket. cups.setServer ("localhost") + except: + nonfatalException () try: connection = authconn.Connection(parent) @@ -905,6 +907,8 @@ class GUI(GtkGUI, monitor.Watcher): show_IPP_Error(e, s, parent) gtk.gdk.threads_leave() return + except: + nonfatalException () if self.connect_thread != thread.get_ident(): return gtk.gdk.threads_enter() @@ -919,6 +923,8 @@ class GUI(GtkGUI, monitor.Watcher): self.setConnected() self.populateList() show_HTTP_Error(s, parent) + except: + nonfatalException () gtk.gdk.threads_leave() @@ -3055,7 +3061,7 @@ class NewPrinterGUI(GtkGUI): except cups.IPPError, (e, msg): self.devices_result = cups.IPPError (e, msg) except: - debugprint ("Exception in getDevices_thread") + nonfatalException () self.devices_result = {} try: -- 1.5.4.3 From bd352db6120e549b54de724b11ef4e38d0abadae Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 5 Jun 2008 09:36:19 +0100 Subject: [PATCH] Added show_info_dialog(). * errordialogs.py (show_dialog): New function. (show_error_dialog): Use it. (show_info_dialog): New function. (cherry picked from commit 73c7ffe570293a898b257c4da938d147a0ab97db) --- ChangeLog | 6 ++++++ errordialogs.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad38111..5ddda89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-06-05 Tim Waugh + + * errordialogs.py (show_dialog): New function. + (show_error_dialog): Use it. + (show_info_dialog): New function. + 2008-06-04 Tim Waugh * system-config-printer.py (GUI.connect): Always show traceback diff --git a/errordialogs.py b/errordialogs.py index 6590c88..900b4a3 100755 --- a/errordialogs.py +++ b/errordialogs.py @@ -28,7 +28,7 @@ def set_gettext_function (fn): global _ _ = fn -def show_error_dialog (title, text, parent=None): +def show_dialog (title, text, icon, parent=None): dialog = gtk.Dialog (title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, @@ -39,7 +39,7 @@ def show_error_dialog (title, text, parent=None): hbox = gtk.HBox (False, 12) hbox.set_border_width (6) image = gtk.Image () - image.set_from_stock ('gtk-dialog-error', gtk.ICON_SIZE_DIALOG) + image.set_from_stock (icon, gtk.ICON_SIZE_DIALOG) image.set_alignment (0.0, 0.0) hbox.pack_start (image, False, False, 0) label = gtk.Label () @@ -54,6 +54,12 @@ def show_error_dialog (title, text, parent=None): dialog.run () dialog.hide () +def show_info_dialog (title, text, parent=None): + return show_dialog (title, text, 'gtk-dialog-info', parent=parent) + +def show_error_dialog (title, text, parent=None): + return show_dialog (title, text, 'gtk-dialog-error', parent=parent) + def show_IPP_Error(exception, message, parent=None): if exception == cups.IPP_NOT_AUTHORIZED: title = _('Not authorized') -- 1.5.4.3 From 3ec292e6cb2fabda0dae46fac50828167c65a1ac Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 5 Jun 2008 09:38:09 +0100 Subject: [PATCH] Added Firewall Review dialog. * system-config-printer.py (GUI.save_serversettings): Show a dialog advising the user to review the firewall if sharing has been enabled. (cherry picked from commit b17f98e2d9f42eb2a27643a081ff0317a1f50d6f) --- ChangeLog | 6 ++++++ system-config-printer.py | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ddda89..080efbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-06-05 Tim Waugh + * system-config-printer.py (GUI.save_serversettings): Show a + dialog advising the user to review the firewall if sharing has + been enabled. + +2008-06-05 Tim Waugh + * errordialogs.py (show_dialog): New function. (show_error_dialog): Use it. (show_info_dialog): New function. diff --git a/system-config-printer.py b/system-config-printer.py index aa2d46f..8a1609f 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -2189,6 +2189,26 @@ class GUI(GtkGUI, monitor.Watcher): return True self.changed = set() self.setDataButtonState() + + old_setting = self.server_settings.get (cups.CUPS_SERVER_SHARE_PRINTERS, + '0') + new_setting = setting_dict.get (cups.CUPS_SERVER_SHARE_PRINTERS, '0') + if (old_setting == '0' and new_setting != '0'): + # We have just enabled print queue sharing. + # Ideally, this is the time we would check the firewall + # settings on this machine and request that the IPP TCP port + # be unblocked. Unfortunately, this is not yet possible + # (bug #440469). However, we can display a dialog to suggest + # that now might be a good time to review the firewall settings. + show_info_dialog (_("Review Firewall"), + _("You may need to adjust the firewall " + "to allow network printing to this " + "computer.") + '\n\n' + + _("To do this, select " + "System->Administration->Firewall " + "from the main menu."), + parent=self.ServerSettingsDialog) + time.sleep(1) # give the server a chance to process our request # Now reconnect, in case the server needed to reload. -- 1.5.4.3 From e19c238a85fc422ed5cfedd3ddcaa8a3d4714e0d Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 5 Jun 2008 15:08:43 +0100 Subject: [PATCH] Don't show non-fatal exception message for IPP browse errors. * system-config-printer.py (NewPrinterGUI.browse_ipp_queues_thread): IPP errors are fine here. (cherry picked from commit 376bea144c59c302456b4e3a14fc31063a87411f) --- ChangeLog | 6 ++++++ system-config-printer.py | 3 +++ 2 files changed, 9 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index 080efbb..591ffe0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-06-05 Tim Waugh + * system-config-printer.py + (NewPrinterGUI.browse_ipp_queues_thread): IPP errors are fine + here. + +2008-06-05 Tim Waugh + * system-config-printer.py (GUI.save_serversettings): Show a dialog advising the user to review the firewall if sharing has been enabled. diff --git a/system-config-printer.py b/system-config-printer.py index 8a1609f..14b6c9a 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -3831,6 +3831,9 @@ class NewPrinterGUI(GtkGUI): c = cups.Connection() printers = c.getPrinters () del c + except cups.IPPError, (e, m): + debugprint ("IPP browser: %s" % m) + failed = True except: nonfatalException() failed = True -- 1.5.4.3 From 3a444b7cdd0a892ebf176a32c0242ea362490516 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 5 Jun 2008 15:15:32 +0100 Subject: [PATCH] Better exception handling in threads. * system-config-printer.py (NewPrinterGUI.browse_ipp_queues_thread): Better exception handling. (NewPrinterGUI.browse_smb_hosts_thread): Likewise. (NewPrinterGUI.openprinting_printers_found): Likewise. (cherry picked from commit d2bb9fa39787d0dd5c78163ae31c9a6bdf63720b) --- ChangeLog | 8 ++ system-config-printer.py | 198 ++++++++++++++++++++++++--------------------- 2 files changed, 114 insertions(+), 92 deletions(-) diff --git a/ChangeLog b/ChangeLog index 591ffe0..0868e62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ 2008-06-05 Tim Waugh * system-config-printer.py + (NewPrinterGUI.browse_ipp_queues_thread): Better exception + handling. + (NewPrinterGUI.browse_smb_hosts_thread): Likewise. + (NewPrinterGUI.openprinting_printers_found): Likewise. + +2008-06-05 Tim Waugh + + * system-config-printer.py (NewPrinterGUI.browse_ipp_queues_thread): IPP errors are fine here. diff --git a/system-config-printer.py b/system-config-printer.py index 14b6c9a..149a93d 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -3379,20 +3379,23 @@ class NewPrinterGUI(GtkGUI): """Initialise the SMB tree store.""" gtk.gdk.threads_enter() - store = self.smb_store - store.clear () - if pysmb.USE_OLD_CODE: - store.append(None, (_('Scanning...'), '', None, None)) - else: - class X: - pass - dummy = X() - dummy.smbc_type = pysmb.smbc.PRINTER_SHARE - dummy.name = _('Scanning...') - dummy.comment = '' - store.append(None, [dummy]) try: - self.busy(self.SMBBrowseDialog) + store = self.smb_store + store.clear () + if pysmb.USE_OLD_CODE: + store.append(None, (_('Scanning...'), '', None, None)) + else: + class X: + pass + dummy = X() + dummy.smbc_type = pysmb.smbc.PRINTER_SHARE + dummy.name = _('Scanning...') + dummy.comment = '' + store.append(None, [dummy]) + try: + self.busy(self.SMBBrowseDialog) + except: + nonfatalException() except: nonfatalException() gtk.gdk.threads_leave() @@ -3420,28 +3423,31 @@ class NewPrinterGUI(GtkGUI): nonfatalException() gtk.gdk.threads_enter() - if pysmb.USE_OLD_CODE: - store.clear () - for domain in domains.keys (): - d = domains[domain] - iter = store.append (None) - if iter: - dummy = store.append (iter) - store.set_value (iter, 0, d['DOMAIN']) - store.set_value (iter, 2, d) - else: - store.clear () - if workgroups: - for workgroup in workgroups: - iter = store.append (None, [workgroup]) - i = store.append (iter) - try: - self.ready(self.SMBBrowseDialog) + if pysmb.USE_OLD_CODE: + store.clear () + for domain in domains.keys (): + d = domains[domain] + iter = store.append (None) + if iter: + dummy = store.append (iter) + store.set_value (iter, 0, d['DOMAIN']) + store.set_value (iter, 2, d) + else: + store.clear () + if workgroups: + for workgroup in workgroups: + iter = store.append (None, [workgroup]) + i = store.append (iter) + + try: + self.ready(self.SMBBrowseDialog) + except: + nonfatalException() + + self.smb_lock.release() except: nonfatalException() - - self.smb_lock.release() gtk.gdk.threads_leave() def smb_select_function (self, path): @@ -3813,15 +3819,18 @@ class NewPrinterGUI(GtkGUI): def browse_ipp_queues_thread(self): gtk.gdk.threads_enter() - store = self.ipp_store - store.clear () - store.append(None, (_('Scanning...'), '', None)) try: - self.busy(self.IPPBrowseDialog) + store = self.ipp_store + store.clear () + store.append(None, (_('Scanning...'), '', None)) + try: + self.busy(self.IPPBrowseDialog) + except: + nonfatalException() + + host = self.entNPTIPPHostname.get_text() except: nonfatalException() - - host = self.entNPTIPPHostname.get_text() gtk.gdk.threads_leave() cups.setServer (host) @@ -3839,33 +3848,35 @@ class NewPrinterGUI(GtkGUI): failed = True gtk.gdk.threads_enter() + try: + store.clear () + for printer, dict in printers.iteritems (): + iter = store.append (None) + store.set_value (iter, 0, printer) + store.set_value (iter, 1, dict.get ('printer-location', '')) + store.set_value (iter, 2, dict) + + if len (printers) + len (classes) == 0: + # Display 'No queues' dialog + if failed: + title = _("Not possible") + text = (_("It is not possible to obtain a list of queues " + "from this host.")) + else: + title = _("No queues") + text = _("There are no queues available.") - store.clear () - for printer, dict in printers.iteritems (): - iter = store.append (None) - store.set_value (iter, 0, printer) - store.set_value (iter, 1, dict.get ('printer-location', '')) - store.set_value (iter, 2, dict) - - if len (printers) + len (classes) == 0: - # Display 'No queues' dialog - if failed: - title = _("Not possible") - text = (_("It is not possible to obtain a list of queues " - "from this host.")) - else: - title = _("No queues") - text = _("There are no queues available.") + self.show_error_dialog (title, text, self.IPPBrowseDialog) + self.IPPBrowseDialog.hide () - self.show_error_dialog (title, text, self.IPPBrowseDialog) - self.IPPBrowseDialog.hide () + try: + self.ready(self.IPPBrowseDialog) + except: + nonfatalException() - try: - self.ready(self.IPPBrowseDialog) + self.ipp_lock.release() except: nonfatalException() - - self.ipp_lock.release() gtk.gdk.threads_leave() def on_tvIPPBrowser_cursor_changed(self, widget): @@ -4152,39 +4163,42 @@ class NewPrinterGUI(GtkGUI): button = self.btnNPDownloadableDriverSearch label = self.btnNPDownloadableDriverSearch_label gtk.gdk.threads_enter () - label.set_text (_("Search")) - button.set_sensitive (True) - if status != 0: - # Should report error. - print printers - print traceback.extract_tb(printers[2], limit=None) - gtk.gdk.threads_leave () - return - - model = gtk.ListStore (str, str) - if len (printers) != 1: - if len (printers) > 1: - first = _("-- Select printer model --") - else: - first = _("-- No matches found --") - - iter = model.append (None) - model.set_value (iter, 0, first) - model.set_value (iter, 1, None) - - sorted_list = [] - for id, name in printers.iteritems (): - sorted_list.append ((id, name)) + try: + label.set_text (_("Search")) + button.set_sensitive (True) + if status != 0: + # Should report error. + print printers + print traceback.extract_tb(printers[2], limit=None) + gtk.gdk.threads_leave () + return - sorted_list.sort (lambda x, y: cups.modelSort (x[1], y[1])) - for id, name in sorted_list: - iter = model.append (None) - model.set_value (iter, 0, name) - model.set_value (iter, 1, id) - combobox = self.cmbNPDownloadableDriverFoundPrinters - combobox.set_model (model) - combobox.set_active (0) - self.setNPButtons () + model = gtk.ListStore (str, str) + if len (printers) != 1: + if len (printers) > 1: + first = _("-- Select printer model --") + else: + first = _("-- No matches found --") + + iter = model.append (None) + model.set_value (iter, 0, first) + model.set_value (iter, 1, None) + + sorted_list = [] + for id, name in printers.iteritems (): + sorted_list.append ((id, name)) + + sorted_list.sort (lambda x, y: cups.modelSort (x[1], y[1])) + for id, name in sorted_list: + iter = model.append (None) + model.set_value (iter, 0, name) + model.set_value (iter, 1, id) + combobox = self.cmbNPDownloadableDriverFoundPrinters + combobox.set_model (model) + combobox.set_active (0) + self.setNPButtons () + except: + nonfatalException() gtk.gdk.threads_leave () def on_cmbNPDownloadableDriverFoundPrinters_changed(self, widget): -- 1.5.4.3 From 7c0e60e53e6042bb03beb70237a45909d8494ab2 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Thu, 5 Jun 2008 15:25:34 +0100 Subject: [PATCH] Fixed IPP browse hang (bug #450120). (NewPrinterGUI.browse_ipp_queues_thread): Fixed typo (bug #450120). (cherry picked from commit 816fff5ef42c435e6e644a600e76ad5f061d4ccb) --- ChangeLog | 5 +++++ system-config-printer.py | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0868e62..97435b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-06-05 Tim Waugh + (NewPrinterGUI.browse_ipp_queues_thread): Fixed typo (bug + #450120). + +2008-06-05 Tim Waugh + * system-config-printer.py (NewPrinterGUI.browse_ipp_queues_thread): Better exception handling. diff --git a/system-config-printer.py b/system-config-printer.py index 149a93d..5eb73b2 100755 --- a/system-config-printer.py +++ b/system-config-printer.py @@ -3866,7 +3866,7 @@ class NewPrinterGUI(GtkGUI): title = _("No queues") text = _("There are no queues available.") - self.show_error_dialog (title, text, self.IPPBrowseDialog) + show_error_dialog (title, text, self.IPPBrowseDialog) self.IPPBrowseDialog.hide () try: -- 1.5.4.3