Back to index

system-config-printer  1.3.9+20120706
Public Member Functions | Public Attributes | Static Public Attributes
troubleshoot.PrintTestPage.PrintTestPage Class Reference
Inheritance diagram for troubleshoot.PrintTestPage.PrintTestPage:
Inheritance graph
[legend]
Collaboration diagram for troubleshoot.PrintTestPage.PrintTestPage:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def display
def connect_signals
def disconnect_signals
def collect_answer
def cancel_operation
def handle_dbus_signal
def update_job
def print_clicked
def cancel_clicked
def test_toggled
def update_jobs_list
def can_click_forward
def initial_vbox
 Helper functions.

Public Attributes

 main_label
 main_label_text
 print_button
 cancel_button
 test_cell
 treeview
 yes
 persistent_answers
 authconn
 job_to_iter
 op
 print_sigid
 cancel_sigid
 test_sigid
 sub_id
 bus
 timer
 answers
 jobs
 sub_seq
 troubleshooter

Static Public Attributes

dictionary STATE

Detailed Description

Definition at line 40 of file PrintTestPage.py.


Constructor & Destructor Documentation

def troubleshoot.PrintTestPage.PrintTestPage.__init__ (   self,
  troubleshooter 
)

Definition at line 49 of file PrintTestPage.py.

00049 
00050     def __init__ (self, troubleshooter):
00051         Question.__init__ (self, troubleshooter, "Print test page")
00052         page = gtk.VBox ()
00053         page.set_spacing (12)
00054         page.set_border_width (12)
00055 
00056         label = gtk.Label ()
00057         label.set_alignment (0, 0)
00058         label.set_use_markup (True)
00059         label.set_line_wrap (True)
00060         page.pack_start (label, False, False, 0)
00061         self.main_label = label
00062         self.main_label_text = ('<span weight="bold" size="larger">' +
00063                                 _("Test Page") + '</span>\n\n' +
00064                                 _("Now print a test page.  If you are having "
00065                                   "problems printing a specific document, "
00066                                   "print that document now and mark the print "
00067                                   "job below."))
00068 
00069         hbox = gtk.HButtonBox ()
00070         hbox.set_border_width (0)
00071         hbox.set_spacing (3)
00072         hbox.set_layout (gtk.BUTTONBOX_START)
00073         self.print_button = gtk.Button (_("Print Test Page"))
00074         hbox.pack_start (self.print_button, False, False, 0)
00075 
00076         self.cancel_button = gtk.Button (_("Cancel All Jobs"))
00077         hbox.pack_start (self.cancel_button, False, False, 0)
00078         page.pack_start (hbox, False, False, 0)
00079 
00080         tv = gtk.TreeView ()
00081         test_cell = gtk.CellRendererToggle ()
00082         test = gtk.TreeViewColumn (_("Test"), test_cell, active=0)
00083         job = gtk.TreeViewColumn (_("Job"), gtk.CellRendererText (), text=1)
00084         printer_cell = gtk.CellRendererText ()
00085         printer = gtk.TreeViewColumn (_("Printer"), printer_cell, text=2)
00086         name_cell = gtk.CellRendererText ()
00087         name = gtk.TreeViewColumn (_("Document"), name_cell, text=3)
00088         status = gtk.TreeViewColumn (_("Status"), gtk.CellRendererText (),
00089                                      text=4)
00090         test_cell.set_radio (False)
00091         self.test_cell = test_cell
00092         printer.set_resizable (True)
00093         printer_cell.set_property ("ellipsize", pango.ELLIPSIZE_END)
00094         printer_cell.set_property ("width-chars", 20)
00095         name.set_resizable (True)
00096         name_cell.set_property ("ellipsize", pango.ELLIPSIZE_END)
00097         name_cell.set_property ("width-chars", 20)
00098         status.set_resizable (True)
00099         tv.append_column (test)
00100         tv.append_column (job)
00101         tv.append_column (printer)
00102         tv.append_column (name)
00103         tv.append_column (status)
00104         tv.set_rules_hint (True)
00105         sw = gtk.ScrolledWindow ()
00106         sw.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00107         sw.set_shadow_type (gtk.SHADOW_IN)
00108         sw.add (tv)
00109         self.treeview = tv
00110         page.pack_start (sw)
00111 
00112         label = gtk.Label (_("Did the marked print jobs print correctly?"))
00113         label.set_line_wrap (True)
00114         label.set_alignment (0, 0)
00115         page.pack_start (label, False, False, 0)
00116 
00117         vbox = gtk.VBox ()
00118         vbox.set_spacing (6)
00119         self.yes = gtk.RadioButton (label=_("Yes"))
00120         no = gtk.RadioButton (label=_("No"))
00121         no.set_group (self.yes)
00122         vbox.pack_start (self.yes, False, False, 0)
00123         vbox.pack_start (no, False, False, 0)
00124         page.pack_start (vbox, False, False, 0)
00125         self.persistent_answers = {}
00126         troubleshooter.new_page (page, self)


Member Function Documentation

Definition at line 435 of file PrintTestPage.py.

00435 
00436     def cancel_clicked (self, widget):
00437         self.persistent_answers['test_page_jobs_cancelled'] = True
00438         jobids = []
00439         for jobid, iter in self.job_to_iter.iteritems ():
00440             jobids.append (jobid)
00441 
00442         def cancel_jobs (jobids):
00443             c = self.authconn
00444             for jobid in jobids:
00445                 try:
00446                     c.cancelJob (jobid)
00447                 except cups.IPPError, (e, s):
00448                     if e != cups.IPP_NOT_POSSIBLE:
00449                         self.persistent_answers['test_page_cancel_failure'] = (e, s)
00450 
00451         self.op = TimedOperation (cancel_jobs,
00452                                   (jobids,),
00453                                   parent=self.troubleshooter.get_window ())
00454         try:
00455             self.op.run ()
00456         except (OperationCanceled, cups.IPPError):
00457             pass

Reimplemented from troubleshoot.base.Question.

Definition at line 336 of file PrintTestPage.py.

00336 
00337     def cancel_operation (self):
00338         self.op.cancel ()
00339 
00340         # Abandon the CUPS connection and make another.
00341         answers = self.troubleshooter.answers
00342         factory = answers['_authenticated_connection_factory']
00343         self.authconn = factory.get_connection ()
00344         self.answers['_authenticated_connection'] = self.authconn

Reimplemented from troubleshoot.base.Question.

Definition at line 286 of file PrintTestPage.py.

00286 
00287     def collect_answer (self):
00288         if not self.displayed:
00289             return {}
00290 
00291         self.answers = self.persistent_answers.copy ()
00292         parent = self.troubleshooter.get_window ()
00293         success = self.yes.get_active ()
00294         self.answers['test_page_successful'] = success
00295 
00296         class collect_jobs:
00297             def __init__ (self, model):
00298                 self.jobs = []
00299                 model.foreach (self.each, None)
00300 
00301             def each (self, model, path, iter, user_data):
00302                 self.jobs.append (model.get (iter, 0, 1, 2, 3, 4))
00303 
00304         model = self.treeview.get_model ()
00305         jobs = collect_jobs (model).jobs
00306         def collect_attributes (jobs):
00307             job_attrs = None
00308             c = self.authconn
00309             with_attrs = []
00310             for (test, jobid, printer, doc, status) in jobs:
00311                 attrs = None
00312                 if test:
00313                     try:
00314                         attrs = c.getJobAttributes (jobid)
00315                     except AttributeError:
00316                         # getJobAttributes was introduced in pycups 1.9.35.
00317                         if job_attrs == None:
00318                             job_attrs = c.getJobs (which_jobs='all')
00319 
00320                         attrs = self.job_attrs[jobid]
00321 
00322                 with_attrs.append ((test, jobid, printer, doc, status, attrs))
00323 
00324             return with_attrs
00325 
00326         self.op = TimedOperation (collect_attributes,
00327                                   (jobs,),
00328                                   parent=parent)
00329         try:
00330             with_attrs = self.op.run ()
00331             self.answers['test_page_job_status'] = with_attrs
00332         except (OperationCanceled, cups.IPPError):
00333             pass
00334 
00335         return self.answers

Reimplemented from troubleshoot.base.Question.

Definition at line 218 of file PrintTestPage.py.

00218 
00219     def connect_signals (self, handler):
00220         self.print_sigid = self.print_button.connect ("clicked",
00221                                                       self.print_clicked)
00222         self.cancel_sigid = self.cancel_button.connect ("clicked",
00223                                                         self.cancel_clicked)
00224         self.test_sigid = self.test_cell.connect ('toggled',
00225                                                   self.test_toggled)
00226 
00227         def create_subscription ():
00228             c = self.authconn
00229             sub_id = c.createSubscription ("/",
00230                                            events=["job-created",
00231                                                    "job-completed",
00232                                                    "job-stopped",
00233                                                    "job-progress",
00234                                                    "job-state-changed"])
00235             return sub_id
00236 
00237         parent = self.troubleshooter.get_window ()
00238         self.op = TimedOperation (create_subscription, parent=parent)
00239         try:
00240             self.sub_id = self.op.run ()
00241         except (OperationCanceled, cups.IPPError):
00242             pass
00243 
00244         try:
00245             bus = dbus.SystemBus ()
00246         except:
00247             bus = None
00248 
00249         self.bus = bus
00250         if bus:
00251             bus.add_signal_receiver (self.handle_dbus_signal,
00252                                      path=DBUS_PATH,
00253                                      dbus_interface=DBUS_IFACE)
00254 
00255         self.timer = gobject.timeout_add_seconds (1, self.update_jobs_list)

Reimplemented from troubleshoot.base.Question.

Definition at line 256 of file PrintTestPage.py.

00256 
00257     def disconnect_signals (self):
00258         if self.bus:
00259             self.bus.remove_signal_receiver (self.handle_dbus_signal,
00260                                              path=DBUS_PATH,
00261                                              dbus_interface=DBUS_IFACE)
00262                                              
00263         self.print_button.disconnect (self.print_sigid)
00264         self.cancel_button.disconnect (self.cancel_sigid)
00265         self.test_cell.disconnect (self.test_sigid)
00266 
00267         def cancel_subscription (sub_id):
00268             c = self.authconn
00269             c.cancelSubscription (sub_id)
00270 
00271         parent = self.troubleshooter.get_window ()
00272         self.op = TimedOperation (cancel_subscription,
00273                                   (self.sub_id,),
00274                                   parent=parent)
00275         try:
00276             self.op.run ()
00277         except (OperationCanceled, cups.IPPError):
00278             pass
00279 
00280         try:
00281             del self.sub_seq
00282         except:
00283             pass
00284 
00285         gobject.source_remove (self.timer)

Here is the call graph for this function:

Returns True if this page should be displayed, or False
if it should be skipped.

Reimplemented from troubleshoot.base.Question.

Definition at line 127 of file PrintTestPage.py.

00127 
00128     def display (self):
00129         answers = self.troubleshooter.answers
00130         if not answers.has_key ('cups_queue'):
00131             return False
00132 
00133         parent = self.troubleshooter.get_window ()
00134         self.authconn = answers['_authenticated_connection']
00135         mediatype = None
00136         defaults = answers.get ('cups_printer_ppd_defaults', {})
00137         for opts in defaults.values ():
00138             for opt, value in opts.iteritems ():
00139                 if opt == "MediaType":
00140                     mediatype = value
00141                     break
00142 
00143         if mediatype != None:
00144             mediatype_string = '\n\n' + (_("Remember to load paper of type "
00145                                            "'%s' into the printer first.") %
00146                                          mediatype)
00147         else:
00148             mediatype_string = ""
00149 
00150         label_text = self.main_label_text + mediatype_string
00151         self.main_label.set_markup (label_text)
00152 
00153         model = gtk.ListStore (gobject.TYPE_BOOLEAN,
00154                                gobject.TYPE_INT,
00155                                gobject.TYPE_STRING,
00156                                gobject.TYPE_STRING,
00157                                gobject.TYPE_STRING)
00158         self.treeview.set_model (model)
00159         self.job_to_iter = {}
00160 
00161         test_jobs = self.persistent_answers.get ('test_page_job_id', [])
00162         def get_jobs ():
00163             c = self.authconn
00164             try:
00165                 r = ["job-id",
00166                      "job-name",
00167                      "job-state",
00168                      "job-printer-uri",
00169                      "printer-name"]
00170                 jobs_dict = c.getJobs (which_jobs='not-completed',
00171                                        my_jobs=False,
00172                                        requested_attributes=r)
00173                 completed_jobs_dict = c.getJobs (which_jobs='completed',
00174                                                  requested_attributes=r)
00175             except TypeError:
00176                 # requested_attributes requires pycups 1.9.50
00177                 jobs_dict = c.getJobs (which_jobs='not-completed',
00178                                        my_jobs=False)
00179                 completed_jobs_dict = c.getJobs (which_jobs='completed')
00180             return (jobs_dict, completed_jobs_dict)
00181 
00182         self.op = TimedOperation (get_jobs, parent=parent)
00183         try:
00184             (jobs_dict, completed_jobs_dict) = self.op.run ()
00185         except (OperationCanceled, cups.IPPError):
00186             return False
00187 
00188         # We want to display the jobs in the queue for this printer...
00189         try:
00190             queue_uri_ending = "/" + self.troubleshooter.answers['cups_queue']
00191             jobs_on_this_printer = filter (lambda x:
00192                                                jobs_dict[x]['job-printer-uri'].\
00193                                                endswith (queue_uri_ending),
00194                                            jobs_dict.keys ())
00195         except:
00196             jobs_on_this_printer = []
00197 
00198         # ...as well as any other jobs we've previous submitted as test pages.
00199         jobs = list (set(test_jobs).union (set (jobs_on_this_printer)))
00200 
00201         completed_jobs_dict = None
00202         for job in jobs:
00203             try:
00204                 j = jobs_dict[job]
00205             except KeyError:
00206                 try:
00207                     j = completed_jobs_dict[job]
00208                 except KeyError:
00209                     continue
00210 
00211             iter = model.append (None)
00212             self.job_to_iter[job] = iter
00213             model.set_value (iter, 0, job in test_jobs)
00214             model.set_value (iter, 1, job)
00215             self.update_job (job, j)
00216 
00217         return True

Definition at line 345 of file PrintTestPage.py.

00345 
00346     def handle_dbus_signal (self, *args):
00347         debugprint ("D-Bus signal caught: updating jobs list soon")
00348         gobject.source_remove (self.timer)
00349         self.timer = gobject.timeout_add (200, self.update_jobs_list)

Here is the call graph for this function:

Here is the caller graph for this function:

def troubleshoot.base.Question.initial_vbox (   self,
  title = '',
  text = '' 
) [inherited]

Helper functions.

Definition at line 66 of file base.py.

00066 
00067     def initial_vbox (self, title='', text=''):
00068         vbox = gtk.VBox ()
00069         vbox.set_border_width (12)
00070         vbox.set_spacing (12)
00071         if title:
00072             s = '<span weight="bold" size="larger">' + title + '</span>\n\n'
00073         else:
00074             s = ''
00075         s += text
00076         label = gtk.Label (s)
00077         label.set_alignment (0, 0)
00078         label.set_line_wrap (True)
00079         label.set_use_markup (True)
00080         vbox.pack_start (label, False, False, 0)
00081         return vbox

Here is the caller graph for this function:

Definition at line 369 of file PrintTestPage.py.

00369 
00370     def print_clicked (self, widget):
00371         now = time.time ()
00372         tt = time.localtime (now)
00373         when = time.strftime ("%d/%b/%Y:%T %z", tt)
00374         self.persistent_answers['test_page_attempted'] = when
00375         answers = self.troubleshooter.answers
00376         parent = self.troubleshooter.get_window ()
00377 
00378         def print_test_page (*args, **kwargs):
00379             factory = answers['_authenticated_connection_factory']
00380             c = factory.get_connection ()
00381             return c.printTestPage (*args, **kwargs)
00382 
00383         tmpfname = None
00384         mimetypes = [None, 'text/plain']
00385         for mimetype in mimetypes:
00386             try:
00387                 if mimetype == None:
00388                     # Default test page.
00389                     self.op = TimedOperation (print_test_page,
00390                                               (answers['cups_queue'],),
00391                                               parent=parent)
00392                     jobid = self.op.run ()
00393                 elif mimetype == 'text/plain':
00394                     (tmpfd, tmpfname) = tempfile.mkstemp ()
00395                     os.write (tmpfd, "This is a test page.\n")
00396                     os.close (tmpfd)
00397                     self.op = TimedOperation (print_test_page,
00398                                               (answers['cups_queue'],),
00399                                               kwargs={'file': tmpfname,
00400                                                       'format': mimetype},
00401                                               parent=parent)
00402                     jobid = self.op.run ()
00403                     try:
00404                         os.unlink (tmpfname)
00405                     except OSError:
00406                         pass
00407 
00408                     tmpfname = None
00409 
00410                 jobs = self.persistent_answers.get ('test_page_job_id', [])
00411                 jobs.append (jobid)
00412                 self.persistent_answers['test_page_job_id'] = jobs
00413                 break
00414             except OperationCanceled:
00415                 self.persistent_answers['test_page_submit_failure'] = 'cancel'
00416                 break
00417             except RuntimeError:
00418                 self.persistent_answers['test_page_submit_failure'] = 'connect'
00419                 break
00420             except cups.IPPError, (e, s):
00421                 if (e == cups.IPP_DOCUMENT_FORMAT and
00422                     mimetypes.index (mimetype) < (len (mimetypes) - 1)):
00423                     # Try next format.
00424                     if tmpfname != None:
00425                         os.unlink (tmpfname)
00426                         tmpfname = None
00427                     continue
00428 
00429                 self.persistent_answers['test_page_submit_failure'] = (e, s)
00430                 show_error_dialog (_("Error submitting test page"),
00431                                    _("There was an error during the CUPS "
00432                                      "operation: '%s'.") % s,
00433                                    self.troubleshooter.get_window ())
00434                 break

def troubleshoot.PrintTestPage.PrintTestPage.test_toggled (   self,
  cell,
  path 
)

Definition at line 458 of file PrintTestPage.py.

00458 
00459     def test_toggled (self, cell, path):
00460         model = self.treeview.get_model ()
00461         iter = model.get_iter (path)
00462         active = model.get_value (iter, 0)
00463         model.set_value (iter, 0, not active)

def troubleshoot.PrintTestPage.PrintTestPage.update_job (   self,
  jobid,
  job_dict 
)

Definition at line 350 of file PrintTestPage.py.

00350 
00351     def update_job (self, jobid, job_dict):
00352         iter = self.job_to_iter[jobid]
00353         model = self.treeview.get_model ()
00354         try:
00355             printer_name = job_dict['printer-name']
00356         except KeyError:
00357             try:
00358                 uri = job_dict['job-printer-uri']
00359                 r = uri.rfind ('/')
00360                 printer_name = uri[r + 1:]
00361             except KeyError:
00362                 printer_name = None
00363 
00364         if printer_name != None:
00365             model.set_value (iter, 2, printer_name)
00366 
00367         model.set_value (iter, 3, job_dict['job-name'])
00368         model.set_value (iter, 4, self.STATE[job_dict['job-state']])

Definition at line 464 of file PrintTestPage.py.

00464 
00465     def update_jobs_list (self):
00466         def get_notifications (self):
00467             c = self.authconn
00468             try:
00469                 notifications = c.getNotifications ([self.sub_id],
00470                                                     [self.sub_seq + 1])
00471             except AttributeError:
00472                 notifications = c.getNotifications ([self.sub_id])
00473 
00474             return notifications
00475 
00476         # Enter the GDK lock.  We need to do this because we were
00477         # called from a timeout.
00478         gtk.gdk.threads_enter ()
00479 
00480         parent = self.troubleshooter.get_window ()
00481         self.op = TimedOperation (get_notifications,
00482                                   (self,),
00483                                   parent=parent)
00484         try:
00485             notifications = self.op.run ()
00486         except (OperationCanceled, cups.IPPError):
00487             gtk.gdk.threads_leave ()
00488             return True
00489 
00490         answers = self.troubleshooter.answers
00491         model = self.treeview.get_model ()
00492         queue = answers['cups_queue']
00493         test_jobs = self.persistent_answers.get('test_page_job_id', [])
00494         for event in notifications['events']:
00495             seq = event['notify-sequence-number']
00496             try:
00497                 if seq <= self.sub_seq:
00498                     # Work around a bug in pycups < 1.9.34
00499                     continue
00500             except AttributeError:
00501                 pass
00502             self.sub_seq = seq
00503             job = event['notify-job-id']
00504 
00505             nse = event['notify-subscribed-event']
00506             if nse == 'job-created':
00507                 if (job in test_jobs or
00508                     event['printer-name'] == queue):
00509                     iter = model.append (None)
00510                     self.job_to_iter[job] = iter
00511                     model.set_value (iter, 0, True)
00512                     model.set_value (iter, 1, job)
00513                 else:
00514                     continue
00515             elif not self.job_to_iter.has_key (job):
00516                 continue
00517 
00518             if (job in test_jobs and
00519                 nse in ["job-stopped", "job-completed"]):
00520                 comp = self.persistent_answers.get ('test_page_completions', [])
00521                 comp.append ((job, event['notify-text']))
00522                 self.persistent_answers['test_page_completions'] = comp
00523 
00524             self.update_job (job, event)
00525 
00526         # Update again when we're told to. (But we might update sooner if
00527         # there is a D-Bus signal.)
00528         gobject.source_remove (self.timer)
00529         self.timer = gobject.timeout_add_seconds (
00530             notifications['notify-get-interval'],
00531             self.update_jobs_list)
00532         debugprint ("Update again in %ds" %
00533                     notifications['notify-get-interval'])
00534         gtk.gdk.threads_leave ()
00535         return False

Here is the caller graph for this function:


Member Data Documentation

Definition at line 290 of file PrintTestPage.py.

Definition at line 133 of file PrintTestPage.py.

Definition at line 248 of file PrintTestPage.py.

Definition at line 75 of file PrintTestPage.py.

Definition at line 221 of file PrintTestPage.py.

Definition at line 158 of file PrintTestPage.py.

Definition at line 297 of file PrintTestPage.py.

Definition at line 60 of file PrintTestPage.py.

Definition at line 61 of file PrintTestPage.py.

Definition at line 181 of file PrintTestPage.py.

Definition at line 124 of file PrintTestPage.py.

Definition at line 72 of file PrintTestPage.py.

Definition at line 219 of file PrintTestPage.py.

Initial value:
{ cups.IPP_JOB_PENDING: _("Pending"),
              cups.IPP_JOB_HELD: _("Held"),
              cups.IPP_JOB_PROCESSING: _("Processing"),
              cups.IPP_JOB_STOPPED: _("Stopped"),
              cups.IPP_JOB_CANCELED: _("Canceled"),
              cups.IPP_JOB_ABORTED: _("Aborted"),
              cups.IPP_JOB_COMPLETED: _("Completed") }

Definition at line 41 of file PrintTestPage.py.

Definition at line 239 of file PrintTestPage.py.

Definition at line 501 of file PrintTestPage.py.

Definition at line 90 of file PrintTestPage.py.

Definition at line 223 of file PrintTestPage.py.

Definition at line 254 of file PrintTestPage.py.

Definition at line 108 of file PrintTestPage.py.

Reimplemented in troubleshoot.CheckPrinterSanity.CheckPrinterSanity.

Definition at line 41 of file base.py.

Definition at line 118 of file PrintTestPage.py.


The documentation for this class was generated from the following file: