Back to index

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

List of all members.

Public Member Functions

def __init__
def cleanup
def set_process_pending
def on_delete_event
def job_attributes_on_delete_event
def show_IPP_Error
def toggle_window_display
def on_show_completed_jobs_clicked
def update_job_creation_times
def print_error_dialog_response
def on_troubleshoot_quit
def add_job
def update_monitor
def update_job
def display_auth_info_dialog
def auth_info_dialog_delete
def auth_info_dialog_response
def set_statusicon_visibility
def on_treeview_popup_menu
def on_treeview_button_release_event
def update_sensitivity
def on_selection_changed
def show_treeview_popup_menu
def on_icon_popupmenu
def on_icon_hide_activate
def on_icon_configure_printers_activate
def poll_subprocess
def on_icon_quit_activate
def on_job_cancel_activate
def on_job_delete_activate
def on_job_cancel_activate2
def on_canceljobs_finished
def on_canceljobs_error
def on_job_hold_activate
def on_job_release_activate
def on_job_reprint_activate
def on_job_retrieve_activate
def on_job_move_activate
def on_job_authenticate_activate
def on_refresh_clicked
def on_job_attributes_activate
def update_job_attributes_viewer
def job_is_active
def add_state_reason_emblem
 Icon manipulation.
def get_icon_pixbuf
def set_statusicon_tooltip
def update_status
def notify_printer_state_reason_if_important
 Notifications.
def notify_printer_state_reason
def on_state_reason_notification_closed
def notify_completed_job
def on_completed_job_notification_closed
def on_refresh
 Monitor signal handlers.
def job_added
def job_event
def job_removed
def state_reason_added
def state_reason_removed
def still_connecting
def now_connected
def printer_added
def printer_event
def printer_removed
def getWidgets

Public Attributes

 loop
 applet
 suppress_icon_hide
 my_jobs
 specific_dests
 notify_has_actions
 notify_has_persistence
 jobs
 jobiters
 jobids
 jobs_attrs
 active_jobs
 stopped_job_prompts
 printer_state_reasons
 num_jobs_when_hidden
 connecting_to_device
 state_reason_notifications
 auth_info_dialogs
 job_creation_times_timer
 new_printer_notifications
 completed_job_notifications
 authenticated_jobs
 ops
 job_ui_manager
 job_context_menu
 move_job_menuitem
 store
 selection
 icon_jobs
 icon_jobs_processing
 icon_no_jobs
 statusicon
 host
 port
 encryption
 monitor
 my_monitor
 JobsAttributesWindow
 attrs_ui_manager
 notebook
 process_pending_events
 troubleshooter
 worst_reason
 printer_uri_index

Static Public Attributes

tuple required_job_attributes

Private Member Functions

def _set_job_job_number_text
 Cell data functions.
def _set_job_user_text
def _set_job_document_text
def _set_job_printer_text
def _set_job_size_text
def _find_job_state_text
def _set_job_status_icon
def _set_job_status_text

Static Private Attributes

dictionary __gsignals__

Detailed Description

Definition at line 312 of file jobviewer.py.


Constructor & Destructor Documentation

def jobviewer.JobViewer.__init__ (   self,
  bus = None,
  loop = None,
  applet = False,
  suppress_icon_hide = False,
  my_jobs = True,
  specific_dests = None,
  parent = None 
)

Definition at line 328 of file jobviewer.py.

00328 
00329                  parent=None):
00330         gobject.GObject.__init__ (self)
00331         self.loop = loop
00332         self.applet = applet
00333         self.suppress_icon_hide = suppress_icon_hide
00334         self.my_jobs = my_jobs
00335         self.specific_dests = specific_dests
00336         notify_caps = pynotify.get_server_caps ()
00337         self.notify_has_actions = "actions" in notify_caps
00338         self.notify_has_persistence = "persistence" in notify_caps
00339 
00340         self.jobs = {}
00341         self.jobiters = {}
00342         self.jobids = []
00343         self.jobs_attrs = {} # dict of jobid->(GtkListStore, page_index)
00344         self.active_jobs = set() # of job IDs
00345         self.stopped_job_prompts = set() # of job IDs
00346         self.printer_state_reasons = {}
00347         self.num_jobs_when_hidden = 0
00348         self.connecting_to_device = {} # dict of printer->time first seen
00349         self.state_reason_notifications = {}
00350         self.auth_info_dialogs = {} # by job ID
00351         self.job_creation_times_timer = None
00352         self.new_printer_notifications = {}
00353         self.completed_job_notifications = {}
00354         self.authenticated_jobs = set() # of job IDs
00355         self.ops = []
00356 
00357         self.getWidgets ({"JobsWindow":
00358                               ["JobsWindow",
00359                                "treeview",
00360                                "statusbar",
00361                                "toolbar"],
00362                           "statusicon_popupmenu":
00363                               ["statusicon_popupmenu"]},
00364 
00365                          domain=config.PACKAGE)
00366 
00367         job_action_group = gtk.ActionGroup ("JobActionGroup")
00368         job_action_group.add_actions ([
00369                 ("cancel-job", gtk.STOCK_CANCEL, _("_Cancel"), None,
00370                  _("Cancel selected jobs"), self.on_job_cancel_activate),
00371                 ("delete-job", gtk.STOCK_DELETE, _("_Delete"), None,
00372                  _("Delete selected jobs"), self.on_job_delete_activate),
00373                 ("hold-job", gtk.STOCK_MEDIA_PAUSE, _("_Hold"), None,
00374                  _("Hold selected jobs"), self.on_job_hold_activate),
00375                 ("release-job", gtk.STOCK_MEDIA_PLAY, _("_Release"), None,
00376                  _("Release selected jobs"), self.on_job_release_activate),
00377                 ("reprint-job", gtk.STOCK_REDO, _("Re_print"), None,
00378                  _("Reprint selected jobs"), self.on_job_reprint_activate),
00379                 ("retrieve-job", gtk.STOCK_SAVE_AS, _("Re_trieve"), None,
00380                  _("Retrieve selected jobs"), self.on_job_retrieve_activate),
00381                 ("move-job", None, _("_Move To"), None, None, None),
00382                 ("authenticate-job", None, _("_Authenticate"), None, None,
00383                  self.on_job_authenticate_activate),
00384                 ("job-attributes", None, _("_View Attributes"), None, None,
00385                  self.on_job_attributes_activate),
00386                 ("close", gtk.STOCK_CLOSE, None, "<ctrl>w",
00387                  _("Close this window"), self.on_delete_event)
00388                 ])
00389         self.job_ui_manager = gtk.UIManager ()
00390         self.job_ui_manager.insert_action_group (job_action_group, -1)
00391         self.job_ui_manager.add_ui_from_string (
00392 """
00393 <ui>
00394  <accelerator action="cancel-job"/>
00395  <accelerator action="delete-job"/>
00396  <accelerator action="hold-job"/>
00397  <accelerator action="release-job"/>
00398  <accelerator action="reprint-job"/>
00399  <accelerator action="retrieve-job"/>
00400  <accelerator action="move-job"/>
00401  <accelerator action="authenticate-job"/>
00402  <accelerator action="job-attributes"/>
00403  <accelerator action="close"/>
00404 </ui>
00405 """
00406 )
00407         self.job_ui_manager.ensure_update ()
00408         self.JobsWindow.add_accel_group (self.job_ui_manager.get_accel_group ())
00409         self.job_context_menu = gtk.Menu ()
00410         for action_name in ["cancel-job",
00411                             "delete-job",
00412                             "hold-job",
00413                             "release-job",
00414                             "reprint-job",
00415                             "retrieve-job",
00416                             "move-job",
00417                             None,
00418                             "authenticate-job",
00419                             "job-attributes"]:
00420             if not action_name:
00421                 item = gtk.SeparatorMenuItem ()
00422             else:
00423                 action = job_action_group.get_action (action_name)
00424                 action.set_sensitive (False)
00425                 item = action.create_menu_item ()
00426 
00427                 if action_name == 'move-job':
00428                     self.move_job_menuitem = item
00429                     printers = gtk.Menu ()
00430                     item.set_submenu (printers)
00431 
00432             item.show ()
00433             self.job_context_menu.append (item)
00434 
00435         for action_name in ["cancel-job",
00436                             "delete-job",
00437                             "hold-job",
00438                             "release-job",
00439                             "reprint-job",
00440                             "retrieve-job",
00441                             "close"]:
00442             action = job_action_group.get_action (action_name)
00443             action.set_sensitive (action_name == "close")
00444             action.set_is_important (action_name == "close")
00445             item = action.create_tool_item ()
00446             item.show ()
00447             self.toolbar.insert (item, -1)
00448 
00449         for skip, ellipsize, name, setter in \
00450                 [(False, False, _("Job"), self._set_job_job_number_text),
00451                  (True, False, _("User"), self._set_job_user_text),
00452                  (False, True, _("Document"), self._set_job_document_text),
00453                  (False, True, _("Printer"), self._set_job_printer_text),
00454                  (False, False, _("Size"), self._set_job_size_text)]:
00455             if applet and skip:
00456                 # Skip the user column when running as applet.
00457                 continue
00458 
00459             cell = gtk.CellRendererText()
00460             if ellipsize:
00461                 # Ellipsize the 'Document' and 'Printer' columns.
00462                 cell.set_property ("ellipsize", pango.ELLIPSIZE_END)
00463                 cell.set_property ("width-chars", 20)
00464             column = gtk.TreeViewColumn(name, cell)
00465             column.set_cell_data_func (cell, setter)
00466             column.set_resizable(True)
00467             self.treeview.append_column(column)
00468 
00469         cell = gtk.CellRendererText ()
00470         column = gtk.TreeViewColumn (_("Time submitted"), cell, text=1)
00471         column.set_resizable (True)
00472         self.treeview.append_column (column)
00473 
00474         column = gtk.TreeViewColumn (_("Status"))
00475         icon = gtk.CellRendererPixbuf ()
00476         column.pack_start (icon, False)
00477         text = gtk.CellRendererText ()
00478         text.set_property ("ellipsize", pango.ELLIPSIZE_END)
00479         text.set_property ("width-chars", 20)
00480         column.pack_start (text, True)
00481         column.set_cell_data_func (icon, self._set_job_status_icon)
00482         column.set_cell_data_func (text, self._set_job_status_text)
00483         self.treeview.append_column (column)
00484 
00485         self.store = gtk.TreeStore(int, str)
00486         self.store.set_sort_column_id (0, gtk.SORT_DESCENDING)
00487         self.treeview.set_model(self.store)
00488         self.treeview.set_rules_hint (True)
00489         self.selection = self.treeview.get_selection()
00490         self.selection.set_mode(gtk.SELECTION_MULTIPLE)
00491         self.selection.connect('changed', self.on_selection_changed)
00492         self.treeview.connect ('button_release_event',
00493                                self.on_treeview_button_release_event)
00494         self.treeview.connect ('popup-menu', self.on_treeview_popup_menu)
00495 
00496         self.JobsWindow.set_icon_name (ICON)
00497         self.JobsWindow.hide ()
00498 
00499         if specific_dests:
00500             the_dests = reduce (lambda x, y: x + ", " + y, specific_dests)
00501 
00502         if my_jobs:
00503             if specific_dests:
00504                 title = _("my jobs on %s") % the_dests
00505             else:
00506                 title = _("my jobs")
00507         else:
00508             if specific_dests:
00509                 title = "%s" % the_dests
00510             else:
00511                 title = _("all jobs")
00512         self.JobsWindow.set_title (_("Document Print Status (%s)") % title)
00513 
00514         if parent:
00515             self.JobsWindow.set_transient_for (parent)
00516 
00517         def load_icon(theme, icon):
00518             try:
00519                 pixbuf = theme.load_icon (icon, ICON_SIZE, 0)
00520             except gobject.GError:
00521                 debugprint ("No %s icon available" % icon)
00522                 # Just create an empty pixbuf.
00523                 pixbuf = gtk.gdk.Pixbuf (gtk.gdk.COLORSPACE_RGB,
00524                                          True, 8, ICON_SIZE, ICON_SIZE)
00525                 pixbuf.fill (0)
00526             return pixbuf
00527 
00528         theme = gtk.icon_theme_get_default ()
00529         self.icon_jobs = load_icon (theme, ICON)
00530         self.icon_jobs_processing = load_icon (theme, "printer-printing")
00531         self.icon_no_jobs = self.icon_jobs.copy ()
00532         self.icon_no_jobs.fill (0)
00533         self.icon_jobs.composite (self.icon_no_jobs,
00534                                   0, 0,
00535                                   self.icon_no_jobs.get_width(),
00536                                   self.icon_no_jobs.get_height(),
00537                                   0, 0,
00538                                   1.0, 1.0,
00539                                   gtk.gdk.INTERP_BILINEAR,
00540                                   127)
00541         if self.applet and not self.notify_has_persistence:
00542             self.statusicon = gtk.StatusIcon ()
00543             self.statusicon.set_from_pixbuf (self.icon_no_jobs)
00544             self.statusicon.connect ('activate', self.toggle_window_display)
00545             self.statusicon.connect ('popup-menu', self.on_icon_popupmenu)
00546             self.statusicon.set_visible (False)
00547 
00548         # D-Bus
00549         if bus == None:
00550             bus = dbus.SystemBus ()
00551 
00552         self.set_process_pending (True)
00553         self.host = cups.getServer ()
00554         self.port = cups.getPort ()
00555         self.encryption = cups.getEncryption ()
00556         self.monitor = monitor.Monitor (bus=bus, my_jobs=my_jobs,
00557                                         host=self.host, port=self.port,
00558                                         encryption=self.encryption)
00559         self.monitor.connect ('refresh', self.on_refresh)
00560         self.monitor.connect ('job-added', self.job_added)
00561         self.monitor.connect ('job-event', self.job_event)
00562         self.monitor.connect ('job-removed', self.job_removed)
00563         self.monitor.connect ('state-reason-added', self.state_reason_added)
00564         self.monitor.connect ('state-reason-removed', self.state_reason_removed)
00565         self.monitor.connect ('still-connecting', self.still_connecting)
00566         self.monitor.connect ('now-connected', self.now_connected)
00567         self.monitor.connect ('printer-added', self.printer_added)
00568         self.monitor.connect ('printer-event', self.printer_event)
00569         self.monitor.connect ('printer-removed', self.printer_removed)
00570         self.monitor.refresh ()
00571 
00572         self.my_monitor = None
00573         if not my_jobs:
00574             self.my_monitor = monitor.Monitor(bus=bus, my_jobs=True,
00575                                               host=self.host, port=self.port,
00576                                               encryption=self.encryption)
00577             self.my_monitor.connect ('job-added', self.job_added)
00578             self.my_monitor.connect ('job-event', self.job_event)
00579             self.my_monitor.refresh ()
00580 
00581         if not self.applet:
00582             self.JobsWindow.show ()
00583 
00584         self.JobsAttributesWindow = gtk.Window()
00585         self.JobsAttributesWindow.set_title (_("Job attributes"))
00586         self.JobsAttributesWindow.set_position(gtk.WIN_POS_MOUSE)
00587         self.JobsAttributesWindow.set_default_size(600, 600)
00588         self.JobsAttributesWindow.set_transient_for (self.JobsWindow)
00589         self.JobsAttributesWindow.connect("delete_event",
00590                                           self.job_attributes_on_delete_event)
00591         self.JobsAttributesWindow.add_accel_group (self.job_ui_manager.get_accel_group ())
00592         attrs_action_group = gtk.ActionGroup ("AttrsActionGroup")
00593         attrs_action_group.add_actions ([
00594                 ("close", gtk.STOCK_CLOSE, None, "<ctrl>w",
00595                  _("Close this window"), self.job_attributes_on_delete_event)
00596                 ])
00597         self.attrs_ui_manager = gtk.UIManager ()
00598         self.attrs_ui_manager.insert_action_group (attrs_action_group, -1)
00599         self.attrs_ui_manager.add_ui_from_string (
00600 """
00601 <ui>
00602  <accelerator action="close"/>
00603 </ui>
00604 """
00605 )
00606         self.attrs_ui_manager.ensure_update ()
00607         self.JobsAttributesWindow.add_accel_group (self.attrs_ui_manager.get_accel_group ())
00608         vbox = gtk.VBox ()
00609         self.JobsAttributesWindow.add (vbox)
00610         toolbar = gtk.Toolbar ()
00611         action = self.attrs_ui_manager.get_action ("/close")
00612         item = action.create_tool_item ()
00613         item.set_is_important (True)
00614         toolbar.insert (item, 0)
00615         vbox.pack_start (toolbar, False, False, 0)
00616         self.notebook = gtk.Notebook()
00617         vbox.pack_start (self.notebook)


Member Function Documentation

def jobviewer.JobViewer._find_job_state_text (   self,
  job 
) [private]

Definition at line 2169 of file jobviewer.py.

02169 
02170     def _find_job_state_text (self, job):
02171         data = self.jobs[job]
02172         jstate = data.get ('job-state', cups.IPP_JOB_PROCESSING)
02173         s = int (jstate)
02174         job_requires_auth = (s == cups.IPP_JOB_HELD and
02175                              data.get ('job-hold-until', 'none') ==
02176                              'auth-info-required')
02177         state = None
02178         if job_requires_auth:
02179             state = _("Held for authentication")
02180         elif s == cups.IPP_JOB_HELD:
02181             state = _("Held")
02182             until = data.get ('job-hold-until')
02183             if until != None:
02184                 try:
02185                     colon1 = until.find (':')
02186                     if colon1 != -1:
02187                         now = time.gmtime ()
02188                         hh = int (until[:colon1])
02189                         colon2 = until[colon1 + 1:].find (':')
02190                         if colon2 != -1:
02191                             colon2 += colon1 + 1
02192                             mm = int (until[colon1 + 1:colon2])
02193                             ss = int (until[colon2 + 1:])
02194                         else:
02195                             mm = int (until[colon1 + 1:])
02196                             ss = 0
02197 
02198                         day = now.tm_mday
02199                         if (hh < now.tm_hour or
02200                             (hh == now.tm_hour and
02201                              (mm < now.tm_min or
02202                               (mm == now.tm_min and ss < now.tm_sec)))):
02203                             day += 1
02204 
02205                         hold = (now.tm_year, now.tm_mon, day,
02206                                 hh, mm, ss, 0, 0, -1)
02207                         old_tz = os.environ.get("TZ")
02208                         os.environ["TZ"] = "UTC"
02209                         simpletime = time.mktime (hold)
02210 
02211                         if old_tz == None:
02212                             del os.environ["TZ"]
02213                         else:
02214                             os.environ["TZ"] = old_tz
02215 
02216                         local = time.localtime (simpletime)
02217                         state = _("Held until %s") % time.strftime ("%X", local)
02218                 except ValueError:
02219                     pass
02220             if until == "day-time":
02221                 state = _("Held until day-time")
02222             elif until == "evening":
02223                 state = _("Held until evening")
02224             elif until == "night":
02225                 state = _("Held until night-time")
02226             elif until == "second-shift":
02227                 state = _("Held until second shift")
02228             elif until == "third-shift":
02229                 state = _("Held until third shift")
02230             elif until == "weekend":
02231                 state = _("Held until weekend")
02232         else:
02233             try:
02234                 state = { cups.IPP_JOB_PENDING: _("Pending"),
02235                           cups.IPP_JOB_PROCESSING: _("Processing"),
02236                           cups.IPP_JOB_STOPPED: _("Stopped"),
02237                           cups.IPP_JOB_CANCELED: _("Canceled"),
02238                           cups.IPP_JOB_ABORTED: _("Aborted"),
02239                           cups.IPP_JOB_COMPLETED: _("Completed") }[s]
02240             except IndexError:
02241                 pass
02242 
02243         if state == None:
02244             state = _("Unknown")
02245 
02246         return state

Here is the caller graph for this function:

def jobviewer.JobViewer._set_job_document_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2147 of file jobviewer.py.

02147 
02148     def _set_job_document_text (self, column, cell, model, iter, *data):
02149         jobid = model.get_value (iter, 0)
02150         job = self.jobs[jobid]
02151         cell.set_property("text", job.get('job-name', _("Unknown")))

def jobviewer.JobViewer._set_job_job_number_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Cell data functions.

Definition at line 2138 of file jobviewer.py.

02138 
02139     def _set_job_job_number_text (self, column, cell, model, iter, *data):
02140         cell.set_property("text", str (model.get_value (iter, 0)))

def jobviewer.JobViewer._set_job_printer_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2152 of file jobviewer.py.

02152 
02153     def _set_job_printer_text (self, column, cell, model, iter, *data):
02154         jobid = model.get_value (iter, 0)
02155         reasons = self.jobs[jobid].get('job-state-reasons')
02156         if reasons == 'printer-stopped':
02157             reason = ' - ' + _("disabled")
02158         else:
02159             reason = ''
02160         cell.set_property("text", self.jobs[jobid]['job-printer-name']+reason)

def jobviewer.JobViewer._set_job_size_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2161 of file jobviewer.py.

02161 
02162     def _set_job_size_text (self, column, cell, model, iter, *data):
02163         jobid = model.get_value (iter, 0)
02164         job = self.jobs[jobid]
02165         size = _("Unknown")
02166         if job.has_key ('job-k-octets'):
02167             size = str (job['job-k-octets']) + 'k'
02168         cell.set_property("text", size)

def jobviewer.JobViewer._set_job_status_icon (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2247 of file jobviewer.py.

02247 
02248     def _set_job_status_icon (self, column, cell, model, iter, *data):
02249         jobid = model.get_value (iter, 0)
02250         data = self.jobs[jobid]
02251         jstate = data.get ('job-state', cups.IPP_JOB_PROCESSING)
02252         s = int (jstate)
02253         if s == cups.IPP_JOB_PROCESSING:
02254             icon = self.icon_jobs_processing
02255         else:
02256             icon = self.icon_jobs
02257 
02258         if s == cups.IPP_JOB_HELD:
02259             theme = gtk.icon_theme_get_default ()
02260             emblem = theme.load_icon (gtk.STOCK_MEDIA_PAUSE, 22 / 2, 0)
02261             copy = icon.copy ()
02262             emblem.composite (copy, 0, 0,
02263                               copy.get_width (),
02264                               copy.get_height (),
02265                               copy.get_width () / 2 - 1,
02266                               copy.get_height () / 2 - 1,
02267                               1.0, 1.0,
02268                               gtk.gdk.INTERP_NEAREST, 255)
02269             icon = copy
02270         else:
02271             # Check state reasons.
02272             printer = data['job-printer-name']
02273             icon = self.add_state_reason_emblem (icon, printer=printer)
02274 
02275         cell.set_property ("pixbuf", icon)

Here is the call graph for this function:

def jobviewer.JobViewer._set_job_status_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2276 of file jobviewer.py.

02276 
02277     def _set_job_status_text (self, column, cell, model, iter, *data):
02278         jobid = model.get_value (iter, 0)
02279         data = self.jobs[jobid]
02280         try:
02281             text = data['_status_text']
02282         except KeyError:
02283             text = self._find_job_state_text (jobid)
02284             data['_status_text'] = text
02285 
02286         printer = data['job-printer-name']
02287         reasons = self.printer_state_reasons.get (printer, [])
02288         if len (reasons) > 0:
02289             worst_reason = reasons[0]
02290             for reason in reasons[1:]:
02291                 if reason > worst_reason:
02292                     worst_reason = reason
02293             (title, unused) = worst_reason.get_description ()
02294             text += " - " + title
02295 
02296         cell.set_property ("text", text)
02297 
02298 gobject.type_register (JobViewer)

Here is the call graph for this function:

def jobviewer.JobViewer._set_job_user_text (   self,
  column,
  cell,
  model,
  iter,
  data 
) [private]

Definition at line 2141 of file jobviewer.py.

02141 
02142     def _set_job_user_text (self, column, cell, model, iter, *data):
02143         jobid = model.get_value (iter, 0)
02144         job = self.jobs[jobid]
02145         cell.set_property("text", job.get ('job-originating-user-name',
02146                                            _("Unknown")))

def jobviewer.JobViewer.add_job (   self,
  job,
  data,
  connection = None 
)

Definition at line 788 of file jobviewer.py.

00788 
00789     def add_job (self, job, data, connection=None):
00790         self.update_job (job, data, connection=connection)
00791 
00792         # There may have been an error fetching additional attributes,
00793         # in which case we need to give up.
00794         if not self.jobs.has_key (job):
00795             return
00796 
00797         store = self.store
00798         iter = self.store.append (None)
00799         store.set_value (iter, 0, job)
00800         debugprint ("Job %d added" % job)
00801         self.jobiters[job] = iter
00802 
00803         range = self.treeview.get_visible_range ()
00804         if range != None:
00805             (start, end) = range
00806             if (self.store.get_sort_column_id () == (0,
00807                                                      gtk.SORT_DESCENDING) and
00808                 start == (1,)):
00809                 # This job was added job above the visible range, and
00810                 # we are sorting by descending job ID.  Scroll to it.
00811                 self.treeview.scroll_to_cell ((0,), None, False, 0.0, 0.0)
00812 
00813         if not self.job_creation_times_timer:
00814             def start_updating_job_creation_times():
00815                 gtk.gdk.threads_enter ()
00816                 self.update_job_creation_times ()
00817                 gtk.gdk.threads_leave ()
00818                 return False
00819 
00820             gobject.timeout_add (500, start_updating_job_creation_times)

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.add_state_reason_emblem (   self,
  pixbuf,
  printer = None 
)

Icon manipulation.

Definition at line 1528 of file jobviewer.py.

01528 
01529     def add_state_reason_emblem (self, pixbuf, printer=None):
01530         worst_reason = None
01531         if printer == None and self.worst_reason != None:
01532             # Check that it's valid.
01533             printer = self.worst_reason.get_printer ()
01534             found = False
01535             for reason in self.printer_state_reasons.get (printer, []):
01536                 if reason == self.worst_reason:
01537                     worst_reason = self.worst_reason
01538                     break
01539             if worst_reason == None:
01540                 self.worst_reason = None
01541 
01542         if printer != None:
01543             for reason in self.printer_state_reasons.get (printer, []):
01544                 if worst_reason == None:
01545                     worst_reason = reason
01546                 elif reason > worst_reason:
01547                     worst_reason = reason
01548 
01549         if worst_reason != None:
01550             level = worst_reason.get_level ()
01551             if level > StateReason.REPORT:
01552                 # Add an emblem to the icon.
01553                 icon = StateReason.LEVEL_ICON[level]
01554                 pixbuf = pixbuf.copy ()
01555                 try:
01556                     theme = gtk.icon_theme_get_default ()
01557                     emblem = theme.load_icon (icon, 22, 0)
01558                     emblem.composite (pixbuf,
01559                                       pixbuf.get_width () / 2,
01560                                       pixbuf.get_height () / 2,
01561                                       emblem.get_width () / 2,
01562                                       emblem.get_height () / 2,
01563                                       pixbuf.get_width () / 2,
01564                                       pixbuf.get_height () / 2,
01565                                       0.5, 0.5,
01566                                       gtk.gdk.INTERP_BILINEAR, 255)
01567                 except gobject.GError:
01568                     debugprint ("No %s icon available" % icon)
01569 
01570         return pixbuf

Here is the caller graph for this function:

def jobviewer.JobViewer.auth_info_dialog_delete (   self,
  dialog,
  event 
)

Definition at line 1032 of file jobviewer.py.

01032 
01033     def auth_info_dialog_delete (self, dialog, event):
01034         self.auth_info_dialog_response (dialog, gtk.RESPONSE_CANCEL)

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.auth_info_dialog_response (   self,
  dialog,
  response 
)

Definition at line 1035 of file jobviewer.py.

01035 
01036     def auth_info_dialog_response (self, dialog, response):
01037         jobid = dialog.get_data ('job-id')
01038         del self.auth_info_dialogs[jobid]
01039 
01040         if response != gtk.RESPONSE_OK:
01041             dialog.destroy ()
01042             return
01043 
01044         auth_info = dialog.get_auth_info ()
01045         try:
01046             c = authconn.Connection (self.JobsWindow,
01047                                      host=self.host,
01048                                      port=self.port,
01049                                      encryption=self.encryption)
01050         except RuntimeError:
01051             debugprint ("Error connecting to CUPS for authentication")
01052             return
01053 
01054         remember = False
01055         c._begin_operation (_("authenticating job"))
01056         try:
01057             c.authenticateJob (jobid, auth_info)
01058             remember = dialog.get_remember_password ()
01059             self.authenticated_jobs.add (jobid)
01060             self.update_monitor ()
01061         except cups.IPPError, (e, m):
01062             self.show_IPP_Error (e, m)
01063 
01064         c._end_operation ()
01065 
01066         if remember:
01067             try:
01068                 keyring = gnomekeyring.get_default_keyring_sync ()
01069                 type = gnomekeyring.ITEM_NETWORK_PASSWORD
01070                 attrs = dialog.get_data ("keyring-attrs")
01071                 auth_info_required = dialog.get_data ('auth-info-required')
01072                 if attrs != None and auth_info_required != None:
01073                     try:
01074                         ind = auth_info_required.index ('username')
01075                         attrs['user'] = auth_info[ind]
01076                     except IndexError:
01077                         pass
01078 
01079                     name = "%s@%s (%s)" % (attrs.get ("user"),
01080                                            attrs.get ("server"),
01081                                            attrs.get ("protocol"))
01082                     ind = auth_info_required.index ('password')
01083                     secret = auth_info[ind]
01084                     id = gnomekeyring.item_create_sync (keyring, type, name,
01085                                                         attrs, secret, True)
01086                     debugprint ("keyring: created id %d for %s" % (id, name))
01087             except:
01088                 nonfatalException ()
01089 
01090         dialog.destroy ()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 618 of file jobviewer.py.

00618 
00619     def cleanup (self):
00620         self.monitor.cleanup ()
00621         if self.my_monitor:
00622             self.my_monitor.cleanup ()
00623 
00624         self.JobsWindow.hide ()
00625 
00626         # Close any open notifications.
00627         for l in [self.new_printer_notifications.values (),
00628                   self.state_reason_notifications.values ()]:
00629             for notification in l:
00630                 if notification.get_data ('closed') != True:
00631                     try:
00632                         notification.close ()
00633                     except glib.GError:
00634                         # Can fail if the notification wasn't even shown
00635                         # yet (as in bug #571603).
00636                         pass
00637                     notification.set_data ('closed', True)
00638 
00639         if self.job_creation_times_timer != None:
00640             gobject.source_remove (self.job_creation_times_timer)
00641             self.job_creation_times_timer = None
00642 
00643         for op in self.ops:
00644             op.destroy ()
00645 
00646         if self.applet and not self.notify_has_persistence:
00647             self.statusicon.set_visible (False)
00648 
00649         self.emit ('finished')

Here is the caller graph for this function:

def jobviewer.JobViewer.display_auth_info_dialog (   self,
  job,
  keyring_attrs = None 
)

Definition at line 993 of file jobviewer.py.

00993 
00994     def display_auth_info_dialog (self, job, keyring_attrs=None):
00995         data = self.jobs[job]
00996         auth_info_required = data['auth-info-required']
00997         dialog = authconn.AuthDialog (auth_info_required=auth_info_required,
00998                                       allow_remember=USE_KEYRING)
00999         dialog.set_data ('keyring-attrs', keyring_attrs)
01000         dialog.set_data ('auth-info-required', auth_info_required)
01001         dialog.set_position (gtk.WIN_POS_CENTER)
01002 
01003         # Pre-fill 'username' field.
01004         auth_info = map (lambda x: '', auth_info_required)
01005         username = pwd.getpwuid (os.getuid ())[0]
01006         if 'username' in auth_info_required:
01007             try:
01008                 ind = auth_info_required.index ('username')
01009                 auth_info[ind] = username
01010                 dialog.set_auth_info (auth_info)
01011             except:
01012                 nonfatalException ()
01013 
01014         # Focus on the first empty field.
01015         index = 0
01016         for field in auth_info_required:
01017             if auth_info[index] == '':
01018                 dialog.field_grab_focus (field)
01019                 break
01020             index += 1
01021 
01022         dialog.set_prompt (_("Authentication required for "
01023                              "printing document `%s' (job %d)") %
01024                            (data.get('job-name', _("Unknown")), job))
01025         self.auth_info_dialogs[job] = dialog
01026         dialog.connect ('response', self.auth_info_dialog_response)
01027         dialog.connect ('delete-event', self.auth_info_dialog_delete)
01028         dialog.set_data ('job-id', job)
01029         dialog.show_all ()
01030         dialog.set_keep_above (True)
01031         dialog.show_now ()

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.get_icon_pixbuf (   self,
  have_jobs = None 
)

Definition at line 1571 of file jobviewer.py.

01571 
01572     def get_icon_pixbuf (self, have_jobs=None):
01573         if not self.applet:
01574             return
01575 
01576         if have_jobs == None:
01577             have_jobs = len (self.jobs.keys ()) > 0
01578 
01579         if have_jobs:
01580             pixbuf = self.icon_jobs
01581             for jobid, jobdata in self.jobs.iteritems ():
01582                 jstate = jobdata.get ('job-state', cups.IPP_JOB_PENDING)
01583                 if jstate == cups.IPP_JOB_PROCESSING:
01584                     pixbuf = self.icon_jobs_processing
01585                     break
01586         else:
01587             pixbuf = self.icon_no_jobs
01588 
01589         try:
01590             pixbuf = self.add_state_reason_emblem (pixbuf)
01591         except:
01592             nonfatalException ()
01593 
01594         return pixbuf

Here is the call graph for this function:

Here is the caller graph for this function:

def gui.GtkGUI.getWidgets (   self,
  widgets,
  domain = None 
) [inherited]

Definition at line 32 of file gui.py.

00032 
00033     def getWidgets(self, widgets, domain=None):
00034         ui_dir = os.environ.get ("SYSTEM_CONFIG_PRINTER_UI",
00035                                  os.path.join (pkgdata, "ui"))
00036         for xmlfile, names in widgets.iteritems ():
00037             bld = gtk.Builder ()
00038 
00039             if domain:
00040                 bld.set_translation_domain (domain)
00041 
00042             bld.add_from_file (os.path.join (ui_dir, xmlfile + ".ui"))
00043             for name in names:
00044                 widget = bld.get_object(name)
00045                 if widget is None:
00046                     raise ValueError, "Widget '%s' not found" % name
00047                 setattr(self, name, widget)
00048 
00049             try:
00050                 win = widget.get_top_level()
00051             except AttributeError:
00052                 win = None
00053             
00054             if win != None:
00055                 gtk.Window.set_focus_on_map(widget.get_top_level (),
00056                                             self.focus_on_map)
00057                 widget.show()
00058 
00059             bld.connect_signals (self)
def jobviewer.JobViewer.job_added (   self,
  mon,
  jobid,
  eventname,
  event,
  jobdata 
)

Definition at line 1789 of file jobviewer.py.

01789 
01790     def job_added (self, mon, jobid, eventname, event, jobdata):
01791         uri = jobdata.get ('job-printer-uri', '')
01792         try:
01793             printer = self.printer_uri_index.lookup (uri)
01794         except KeyError:
01795             printer = uri
01796 
01797         if self.specific_dests and printer not in self.specific_dests:
01798             return
01799 
01800         jobdata['job-printer-name'] = printer
01801 
01802         # We may be showing this job already, perhaps because we are showing
01803         # completed jobs and one was reprinted.
01804         if not self.jobiters.has_key (jobid):
01805             self.add_job (jobid, jobdata)
01806         elif mon == self.my_monitor:
01807             # Copy over any missing attributes such as user and title.
01808             for attr, value in jobdata.iteritems ():
01809                 if not self.jobs[jobid].has_key (attr):
01810                     self.jobs[jobid][attr] = value
01811                     debugprint ("Add %s=%s (my job)" % (attr, value))
01812 
01813         # If we failed to get required attributes for the job, bail.
01814         if not self.jobiters.has_key (jobid):
01815             return
01816 
01817         if self.job_is_active (jobdata):
01818             self.active_jobs.add (jobid)
01819         elif jobid in self.active_jobs:
01820             self.active_jobs.remove (jobid)
01821 
01822         self.update_status (have_jobs=True)
01823         if self.applet:
01824             if not self.job_is_active (jobdata):
01825                 return
01826 
01827             for reason in self.printer_state_reasons.get (printer, []):
01828                 if not reason.user_notified:
01829                     self.notify_printer_state_reason_if_important (reason)

Here is the call graph for this function:

def jobviewer.JobViewer.job_attributes_on_delete_event (   self,
  widget,
  event = None 
)

Definition at line 664 of file jobviewer.py.

00664 
00665     def job_attributes_on_delete_event(self, widget, event=None):
00666         for page in range(self.notebook.get_n_pages()):
00667             self.notebook.remove_page(-1)
00668         self.jobs_attrs = {}
00669         self.JobsAttributesWindow.hide_all()
00670         return True

def jobviewer.JobViewer.job_event (   self,
  mon,
  jobid,
  eventname,
  event,
  jobdata 
)

Definition at line 1830 of file jobviewer.py.

01830 
01831     def job_event (self, mon, jobid, eventname, event, jobdata):
01832         uri = jobdata.get ('job-printer-uri', '')
01833         try:
01834             printer = self.printer_uri_index.lookup (uri)
01835         except KeyError:
01836             printer = uri
01837 
01838         if self.specific_dests and printer not in self.specific_dests:
01839             return
01840 
01841         jobdata['job-printer-name'] = printer
01842 
01843         if self.job_is_active (jobdata):
01844             self.active_jobs.add (jobid)
01845         elif jobid in self.active_jobs:
01846             self.active_jobs.remove (jobid)
01847 
01848         self.update_job (jobid, jobdata)
01849         self.update_status ()
01850 
01851         # Check that the job still exists, as update_status re-enters
01852         # the main loop in order to paint/hide the tray icon.  Really
01853         # that should probably be deferred to the idle handler, but
01854         # for the moment just deal with the fact that the job might
01855         # have gone (bug #640904).
01856         if not self.jobs.has_key (jobid):
01857             return
01858 
01859         jobdata = self.jobs[jobid]
01860 
01861         # If the job has finished, let the user know.
01862         if self.applet and (eventname == 'job-completed' or
01863                             (eventname == 'job-state-changed' and
01864                              event['job-state'] == cups.IPP_JOB_COMPLETED)):
01865             reasons = event['job-state-reasons']
01866             if type (reasons) != list:
01867                 reasons = [reasons]
01868 
01869             canceled = False
01870             for reason in reasons:
01871                 if reason.startswith ("job-canceled"):
01872                     canceled = True
01873                     break
01874 
01875             if not canceled:
01876                 self.notify_completed_job (jobid)
01877 
01878         # Look out for stopped jobs.
01879         if (self.applet and
01880             (eventname == 'job-stopped' or
01881              (eventname == 'job-state-changed' and
01882               event['job-state'] in [cups.IPP_JOB_STOPPED,
01883                                      cups.IPP_JOB_PENDING])) and
01884             not jobid in self.stopped_job_prompts):
01885             # Why has the job stopped?  It might be due to a job error
01886             # of some sort, or it might be that the backend requires
01887             # authentication.  If the latter, the job will be held not
01888             # stopped, and the job-hold-until attribute will be
01889             # 'auth-info-required'.  This was already checked for in
01890             # update_job.
01891             may_be_problem = True
01892             jstate = jobdata['job-state']
01893             if (jstate == cups.IPP_JOB_PROCESSING or
01894                 (jstate == cups.IPP_JOB_HELD and
01895                  jobdata['job-hold-until'] == 'auth-info-required')):
01896                 # update_job already dealt with this.
01897                 may_be_problem = False
01898             else:
01899                 # Other than that, unfortunately the only
01900                 # clue we get is the notify-text, which is not
01901                 # translated into our native language.  We'd better
01902                 # try parsing it.  In CUPS-1.3.6 the possible strings
01903                 # are:
01904                 #
01905                 # "Job stopped due to filter errors; please consult
01906                 # the error_log file for details."
01907                 #
01908                 # "Job stopped due to backend errors; please consult
01909                 # the error_log file for details."
01910                 #
01911                 # "Job held due to backend errors; please consult the
01912                 # error_log file for details."
01913                 #
01914                 # "Authentication is required for job %d."
01915                 # [This case is handled in the update_job method.]
01916                 #
01917                 # "Job stopped due to printer being paused"
01918                 # [This should be ignored, as the job was doing just
01919                 # fine until the printer was stopped for other reasons.]
01920                 notify_text = event['notify-text']
01921                 document = jobdata['job-name']
01922                 if notify_text.find ("backend errors") != -1:
01923                     message = _("There was a problem sending document `%s' "
01924                                 "(job %d) to the printer.") % (document, jobid)
01925                 elif notify_text.find ("filter errors") != -1:
01926                     message = _("There was a problem processing document `%s' "
01927                                 "(job %d).") % (document, jobid)
01928                 elif (notify_text.find ("being paused") != -1 or
01929                       jstate != cups.IPP_JOB_STOPPED):
01930                     may_be_problem = False
01931                 else:
01932                     # Give up and use the provided message untranslated.
01933                     message = _("There was a problem printing document `%s' "
01934                                 "(job %d): `%s'.") % (document, jobid,
01935                                                       notify_text)
01936 
01937             if may_be_problem:
01938                 debugprint ("Problem detected")
01939                 self.toggle_window_display (None, force_show=True)
01940                 dialog = gtk.Dialog (_("Print Error"), self.JobsWindow, 0,
01941                                      (_("_Diagnose"), gtk.RESPONSE_NO,
01942                                         gtk.STOCK_OK, gtk.RESPONSE_OK))
01943                 dialog.set_default_response (gtk.RESPONSE_OK)
01944                 dialog.set_border_width (6)
01945                 dialog.set_resizable (False)
01946                 dialog.set_icon_name (ICON)
01947                 hbox = gtk.HBox (False, 12)
01948                 hbox.set_border_width (6)
01949                 image = gtk.Image ()
01950                 image.set_from_stock (gtk.STOCK_DIALOG_ERROR,
01951                                       gtk.ICON_SIZE_DIALOG)
01952                 hbox.pack_start (image, False, False, 0)
01953                 vbox = gtk.VBox (False, 12)
01954 
01955                 markup = ('<span weight="bold" size="larger">' +
01956                           _("Print Error") + '</span>\n\n' +
01957                           saxutils.escape (message))
01958                 try:
01959                     if event['printer-state'] == cups.IPP_PRINTER_STOPPED:
01960                         name = event['printer-name']
01961                         markup += ' '
01962                         markup += (_("The printer called `%s' has "
01963                                      "been disabled.") % name)
01964                 except KeyError:
01965                     pass
01966 
01967                 label = gtk.Label (markup)
01968                 label.set_use_markup (True)
01969                 label.set_line_wrap (True)
01970                 label.set_alignment (0, 0)
01971                 vbox.pack_start (label, False, False, 0)
01972                 hbox.pack_start (vbox, False, False, 0)
01973                 dialog.vbox.pack_start (hbox)
01974                 dialog.connect ('response',
01975                                 self.print_error_dialog_response, jobid)
01976                 self.stopped_job_prompts.add (jobid)
01977                 dialog.show_all ()

Here is the call graph for this function:

def jobviewer.JobViewer.job_is_active (   self,
  jobdata 
)

Definition at line 1520 of file jobviewer.py.

01520 
01521     def job_is_active (self, jobdata):
01522         state = jobdata.get ('job-state', cups.IPP_JOB_CANCELED)
01523         if state >= cups.IPP_JOB_CANCELED:
01524             return False
01525 
01526         return True

Here is the caller graph for this function:

def jobviewer.JobViewer.job_removed (   self,
  mon,
  jobid,
  eventname,
  event 
)

Definition at line 1978 of file jobviewer.py.

01978 
01979     def job_removed (self, mon, jobid, eventname, event):
01980         # If the job has finished, let the user know.
01981         if self.applet and (eventname == 'job-completed' or
01982                             (eventname == 'job-state-changed' and
01983                              event['job-state'] == cups.IPP_JOB_COMPLETED)):
01984             reasons = event['job-state-reasons']
01985             debugprint (reasons)
01986             if type (reasons) != list:
01987                 reasons = [reasons]
01988 
01989             canceled = False
01990             for reason in reasons:
01991                 if reason.startswith ("job-canceled"):
01992                     canceled = True
01993                     break
01994 
01995             if not canceled:
01996                 self.notify_completed_job (jobid)
01997 
01998         if self.jobiters.has_key (jobid):
01999             self.store.remove (self.jobiters[jobid])
02000             del self.jobiters[jobid]
02001             del self.jobs[jobid]
02002 
02003         if jobid in self.active_jobs:
02004             self.active_jobs.remove (jobid)
02005 
02006         if self.jobs_attrs.has_key (jobid):
02007             del self.jobs_attrs[jobid]
02008 
02009         self.update_status ()

Here is the call graph for this function:

def jobviewer.JobViewer.notify_completed_job (   self,
  jobid 
)

Definition at line 1727 of file jobviewer.py.

01727 
01728     def notify_completed_job (self, jobid):
01729         job = self.jobs.get (jobid, {})
01730         document = job.get ('job-name', _("Unknown"))
01731         printer_uri = job.get ('job-printer-uri')
01732         if printer_uri != None:
01733             # Determine if this printer is remote.  There's no need to
01734             # show a notification if the printer is connected to this
01735             # machine.
01736 
01737             # Find out the device URI.  We might already have
01738             # determined this if authentication was required.
01739             device_uri = job.get ('device-uri')
01740 
01741             if device_uri == None:
01742                 pattrs = ['device-uri']
01743                 c = authconn.Connection (self.JobsWindow,
01744                                          host=self.host,
01745                                          port=self.port,
01746                                          encryption=self.encryption)
01747                 try:
01748                     attrs = c.getPrinterAttributes (uri=printer_uri,
01749                                                     requested_attributes=pattrs)
01750                 except cups.IPPError:
01751                     return
01752 
01753                 device_uri = attrs.get ('device-uri')
01754 
01755             if device_uri != None:
01756                 (scheme, rest) = urllib.splittype (device_uri)
01757                 if scheme not in ['socket', 'ipp', 'http', 'smb']:
01758                     return
01759 
01760         printer = job.get ('job-printer-name', _("Unknown"))
01761         notification = pynotify.Notification (_("Document printed"),
01762                                               _("Document `%s' has been sent "
01763                                                 "to `%s' for printing.") %
01764                                               (document, printer),
01765                                               'printer')
01766         notification.set_urgency (pynotify.URGENCY_LOW)
01767         notification.connect ('closed',
01768                               self.on_completed_job_notification_closed)
01769         notification.set_data ('jobid', jobid)
01770         self.completed_job_notifications[jobid] = notification
01771         self.set_statusicon_visibility ()
01772         try:
01773             notification.show ()
01774         except gobject.GError:
01775             nonfatalException ()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1693 of file jobviewer.py.

01693 
01694     def notify_printer_state_reason (self, reason):
01695         tuple = reason.get_tuple ()
01696         if self.state_reason_notifications.has_key (tuple):
01697             debugprint ("Already sent notification for %s" % repr (reason))
01698             return
01699 
01700         level = reason.get_level ()
01701         if (level == StateReason.ERROR or
01702             reason.get_reason () == "connecting-to-device"):
01703             urgency = pynotify.URGENCY_NORMAL
01704         else:
01705             urgency = pynotify.URGENCY_LOW
01706 
01707         (title, text) = reason.get_description ()
01708         notification = pynotify.Notification (title, text, 'printer')
01709         reason.user_notified = True
01710         notification.set_urgency (urgency)
01711         if self.notify_has_actions:
01712             notification.set_timeout (pynotify.EXPIRES_NEVER)
01713         notification.connect ('closed',
01714                               self.on_state_reason_notification_closed)
01715         self.state_reason_notifications[reason.get_tuple ()] = notification
01716         self.set_statusicon_visibility ()
01717         try:
01718             notification.show ()
01719         except gobject.GError:
01720             nonfatalException ()

Here is the call graph for this function:

Here is the caller graph for this function:

Notifications.

Definition at line 1671 of file jobviewer.py.

01671 
01672     def notify_printer_state_reason_if_important (self, reason):
01673         level = reason.get_level ()
01674         if level < StateReason.WARNING:
01675             # Not important enough to justify a notification.
01676             return
01677 
01678         blacklist = [
01679             # Some printers report 'other-warning' for no apparent
01680             # reason, e.g.  Canon iR 3170C, Epson AL-CX11NF.
01681             # See bug #520815.
01682             "other",
01683 
01684             # This seems to be some sort of 'magic' state reason that
01685             # is for internal use only.
01686             "com.apple.print.recoverable",
01687             ]
01688 
01689         if reason.get_reason () in blacklist:
01690             return
01691 
01692         self.notify_printer_state_reason (reason)

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.now_connected (   self,
  mon,
  printer 
)

Definition at line 2081 of file jobviewer.py.

02081 
02082     def now_connected (self, mon, printer):
02083         if not self.applet:
02084             return
02085 
02086         # Find the connecting-to-device state reason.
02087         try:
02088             reasons = self.printer_state_reasons[printer]
02089             reason = None
02090             for r in reasons:
02091                 if r.get_reason () == "connecting-to-device":
02092                     reason = r
02093                     break
02094         except KeyError:
02095             debugprint ("Couldn't find state reason (no reasons)!")
02096 
02097         if reason != None:
02098             tuple = reason.get_tuple ()
02099         else:
02100             debugprint ("Couldn't find state reason in list!")
02101             tuple = None
02102             for (level,
02103                  p,
02104                  r) in self.state_reason_notifications.keys ():
02105                 if p == printer and r == "connecting-to-device":
02106                     debugprint ("Found from notifications list")
02107                     tuple = (level, p, r)
02108                     break
02109 
02110             if tuple == None:
02111                 debugprint ("Unexpected now_connected signal "
02112                             "(reason not in notifications list)")
02113                 return
02114 
02115         try:
02116             notification = self.state_reason_notifications[tuple]
02117         except KeyError:
02118             debugprint ("Unexpected now_connected signal")
02119             return
02120 
02121         if notification.get_data ('closed') != True:
02122             try:
02123                 notification.close ()
02124             except glib.GError:
02125                 # Can fail if the notification wasn't even shown
02126                 pass
02127             notification.set_data ('closed', True)

def jobviewer.JobViewer.on_canceljobs_error (   self,
  canceljobsoperation,
  jobid,
  exc 
)

Definition at line 1283 of file jobviewer.py.

01283 
01284     def on_canceljobs_error (self, canceljobsoperation, jobid, exc):
01285         self.update_monitor ()
01286         if type (exc) == cups.IPPError:
01287             (e, m) = exc.args
01288             if (e != cups.IPP_NOT_POSSIBLE and
01289                 e != cups.IPP_NOT_FOUND):
01290                 self.show_IPP_Error (e, m)
01291 
01292             return
01293 
01294         raise exc

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_canceljobs_finished (   self,
  canceljobsoperation 
)

Definition at line 1277 of file jobviewer.py.

01277 
01278     def on_canceljobs_finished (self, canceljobsoperation):
01279         canceljobsoperation.destroy ()
01280         i = self.ops.index (canceljobsoperation)
01281         del self.ops[i]
01282         self.update_monitor ()

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_completed_job_notification_closed (   self,
  notification,
  reason = None 
)

Definition at line 1776 of file jobviewer.py.

01776 
01777     def on_completed_job_notification_closed (self, notification, reason=None):
01778         jobid = notification.get_data ('jobid')
01779         del self.completed_job_notifications[jobid]
01780         self.set_statusicon_visibility ()

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_delete_event (   self,
  args 
)

Definition at line 653 of file jobviewer.py.

00653 
00654     def on_delete_event(self, *args):
00655         if self.applet or not self.loop:
00656             self.JobsWindow.hide ()
00657             self.JobsWindow.set_data ('visible', False)
00658             if not self.applet:
00659                 # Being run from main app, not applet
00660                 self.cleanup ()
00661         else:
00662             self.loop.quit ()
00663         return True

Here is the call graph for this function:

Definition at line 1243 of file jobviewer.py.

01243 
01244     def on_icon_configure_printers_activate(self, menuitem):
01245         if self.loop:
01246             env = {}
01247             for name, value in os.environ.iteritems ():
01248                 if name == "SYSTEM_CONFIG_PRINTER_UI":
01249                     continue
01250                 env[name] = value
01251             p = subprocess.Popen ([ "system-config-printer" ],
01252                                   close_fds=True, env=env)
01253             gobject.timeout_add_seconds (10, self.poll_subprocess, p)

Here is the call graph for this function:

def jobviewer.JobViewer.on_icon_hide_activate (   self,
  menuitem 
)

Definition at line 1239 of file jobviewer.py.

01239 
01240     def on_icon_hide_activate(self, menuitem):
01241         self.num_jobs_when_hidden = len (self.jobs.keys ())
01242         self.set_statusicon_visibility ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_icon_popupmenu (   self,
  icon,
  button,
  time 
)

Definition at line 1236 of file jobviewer.py.

01236 
01237     def on_icon_popupmenu(self, icon, button, time):
01238         self.statusicon_popupmenu.popup (None, None, None, button, time)

def jobviewer.JobViewer.on_icon_quit_activate (   self,
  menuitem 
)

Definition at line 1258 of file jobviewer.py.

01258 
01259     def on_icon_quit_activate (self, menuitem):
01260         self.cleanup ()
01261         if self.loop:
01262             self.loop.quit ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_attributes_activate (   self,
  menuitem 
)
For every selected job create notebook page with attributes. 

Definition at line 1456 of file jobviewer.py.

01456 
01457     def on_job_attributes_activate(self, menuitem):
01458         """ For every selected job create notebook page with attributes. """
01459         try:
01460             c = cups.Connection (host=self.host,
01461                                  port=self.port,
01462                                  encryption=self.encryption)
01463         except RuntimeError:
01464             return False
01465 
01466         for jobid in self.jobids:
01467             if jobid not in self.jobs_attrs:
01468                 # add new notebook page with scrollable treeview
01469                 scrolledwindow = gtk.ScrolledWindow()
01470                 label = gtk.Label(str(jobid)) # notebook page has label with jobid
01471                 page_index = self.notebook.append_page(scrolledwindow, label)
01472                 attr_treeview = gtk.TreeView()
01473                 scrolledwindow.add(attr_treeview)
01474                 cell = gtk.CellRendererText ()
01475                 attr_treeview.insert_column_with_attributes(0, _("Name"),
01476                                                             cell, text=0)
01477                 cell = gtk.CellRendererText ()
01478                 attr_treeview.insert_column_with_attributes(1, _("Value"),
01479                                                             cell, text=1)
01480                 attr_store = gtk.ListStore(gobject.TYPE_STRING,
01481                                            gobject.TYPE_STRING)
01482                 attr_treeview.set_model(attr_store)
01483                 attr_treeview.get_selection().set_mode(gtk.SELECTION_NONE)
01484                 attr_store.set_sort_column_id (0, gtk.SORT_ASCENDING)
01485                 self.jobs_attrs[jobid] = (attr_store, page_index)
01486                 self.update_job_attributes_viewer (jobid, conn=c)
01487 
01488         self.JobsAttributesWindow.show_all ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_authenticate_activate (   self,
  menuitem 
)

Definition at line 1445 of file jobviewer.py.

01445 
01446     def on_job_authenticate_activate(self, menuitem):
01447         for jobid in self.jobids:
01448             self.display_auth_info_dialog (jobid)

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_cancel_activate (   self,
  menuitem 
)

Definition at line 1263 of file jobviewer.py.

01263 
01264     def on_job_cancel_activate(self, menuitem):
01265         self.on_job_cancel_activate2(False)

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_cancel_activate2 (   self,
  purge_job 
)

Definition at line 1269 of file jobviewer.py.

01269 
01270     def on_job_cancel_activate2(self, purge_job):
01271         if self.jobids:
01272             op = CancelJobsOperation (self.JobsWindow, self.host, self.port,
01273                                       self.encryption, self.jobids, purge_job)
01274             self.ops.append (op)
01275             op.connect ('finished', self.on_canceljobs_finished)
01276             op.connect ('ipp-error', self.on_canceljobs_error)

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_job_delete_activate (   self,
  menuitem 
)

Definition at line 1266 of file jobviewer.py.

01266 
01267     def on_job_delete_activate(self, menuitem):
01268         self.on_job_cancel_activate2(True)

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_hold_activate (   self,
  menuitem 
)

Definition at line 1295 of file jobviewer.py.

01295 
01296     def on_job_hold_activate(self, menuitem):
01297         try:
01298             c = authconn.Connection (self.JobsWindow,
01299                                      host=self.host,
01300                                      port=self.port,
01301                                      encryption=self.encryption)
01302         except RuntimeError:
01303             return
01304 
01305         for jobid in self.jobids:
01306             c._begin_operation (_("holding job"))
01307             try:
01308                 c.setJobHoldUntil (jobid, "indefinite")
01309             except cups.IPPError, (e, m):
01310                 if (e != cups.IPP_NOT_POSSIBLE and
01311                     e != cups.IPP_NOT_FOUND):
01312                     self.show_IPP_Error (e, m)
01313                 self.update_monitor ()
01314                 c._end_operation ()
01315                 return
01316             c._end_operation ()
01317 
01318         del c
01319         self.update_monitor ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_move_activate (   self,
  menuitem,
  job_printer_uri 
)

Definition at line 1427 of file jobviewer.py.

01427 
01428     def on_job_move_activate(self, menuitem, job_printer_uri):
01429         try:
01430             c = authconn.Connection (self.JobsWindow,
01431                                      host=self.host,
01432                                      port=self.port,
01433                                      encryption=self.encryption)
01434             for jobid in self.jobids:
01435                 c.moveJob (job_id=jobid, job_printer_uri=job_printer_uri)
01436             del c
01437         except cups.IPPError, (e, m):
01438             self.show_IPP_Error (e, m)
01439             self.update_monitor ()
01440             return
01441         except RuntimeError:
01442             return
01443 
01444         self.update_monitor ()

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_job_release_activate (   self,
  menuitem 
)

Definition at line 1320 of file jobviewer.py.

01320 
01321     def on_job_release_activate(self, menuitem):
01322         try:
01323             c = authconn.Connection (self.JobsWindow,
01324                                      host=self.host,
01325                                      port=self.port,
01326                                      encryption=self.encryption)
01327         except RuntimeError:
01328             return
01329 
01330         for jobid in self.jobids:
01331             c._begin_operation (_("releasing job"))
01332             try:
01333                 c.setJobHoldUntil (jobid, "no-hold")
01334             except cups.IPPError, (e, m):
01335                 if (e != cups.IPP_NOT_POSSIBLE and
01336                     e != cups.IPP_NOT_FOUND):
01337                     self.show_IPP_Error (e, m)
01338                 self.update_monitor ()
01339                 c._end_operation ()
01340                 return
01341             c._end_operation ()
01342 
01343         del c
01344         self.update_monitor ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_reprint_activate (   self,
  menuitem 
)

Definition at line 1345 of file jobviewer.py.

01345 
01346     def on_job_reprint_activate(self, menuitem):
01347         try:
01348             c = authconn.Connection (self.JobsWindow,
01349                                      host=self.host,
01350                                      port=self.port,
01351                                      encryption=self.encryption)
01352             for jobid in self.jobids:
01353                 c.restartJob (jobid)
01354             del c
01355         except cups.IPPError, (e, m):
01356             self.show_IPP_Error (e, m)
01357             self.update_monitor ()
01358             return
01359         except RuntimeError:
01360             return
01361 
01362         self.update_monitor ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_job_retrieve_activate (   self,
  menuitem 
)

Definition at line 1363 of file jobviewer.py.

01363 
01364     def on_job_retrieve_activate(self, menuitem):
01365         try:
01366             c = authconn.Connection (self.JobsWindow,
01367                                      host=self.host,
01368                                      port=self.port,
01369                                      encryption=self.encryption)
01370         except RuntimeError:
01371             return
01372 
01373         for jobid in self.jobids:
01374             try:
01375                 attrs=c.getJobAttributes(jobid)
01376                 printer_uri=attrs['job-printer-uri']
01377                 document_count=attrs['document-count']
01378                 for document_number in range(1, document_count+1):
01379                     document=c.getDocument(printer_uri, jobid, document_number)
01380                     tempfile = document.get('file')
01381                     name = document.get('document-name')
01382                     format = document.get('document-format', '')
01383 
01384                     # if there's no document-name retrieved
01385                     if name == None:
01386                         # give the default filename some meaningful name
01387                         name = _("retrieved")+str(document_number)
01388                         # add extension according to format
01389                         if format == 'application/postscript':
01390                             name = name + ".ps"
01391                         elif format.find('application/vnd.') != -1:
01392                             name = name + format.replace('application/vnd', '')
01393                         elif format.find('application/') != -1:
01394                             name = name + format.replace('application/', '.')
01395 
01396                     if tempfile != None:
01397                         dialog = gtk.FileChooserDialog (_("Save File"),
01398                                                         self.JobsWindow,
01399                                                   gtk.FILE_CHOOSER_ACTION_SAVE,
01400                                         (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
01401                                          gtk.STOCK_SAVE, gtk.RESPONSE_OK))
01402                         dialog.set_current_name(name)
01403                         dialog.set_do_overwrite_confirmation(True)
01404 
01405                         response = dialog.run()
01406                         if response == gtk.RESPONSE_OK:
01407                             file_to_save = dialog.get_filename()
01408                             try:
01409                                 shutil.copyfile(tempfile, file_to_save)
01410                             except (IOError, shutil.Error):
01411                                 debugprint("Unable to save file "+file_to_save)
01412                         elif response == gtk.RESPONSE_CANCEL:
01413                             pass
01414                         dialog.destroy()
01415                         os.unlink(tempfile)
01416                     else:
01417                         debugprint("Unable to retrieve file from job file")
01418                         return
01419 
01420             except cups.IPPError, (e, m):
01421                 self.show_IPP_Error (e, m)
01422                 self.update_monitor ()
01423                 return
01424 
01425         del c
01426         self.update_monitor ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_refresh (   self,
  mon 
)

Monitor signal handlers.

Definition at line 1782 of file jobviewer.py.

01782 
01783     def on_refresh (self, mon):
01784         self.store.clear ()
01785         self.jobs = {}
01786         self.active_jobs = set()
01787         self.jobiters = {}
01788         self.printer_uri_index = PrinterURIIndex ()

def jobviewer.JobViewer.on_refresh_clicked (   self,
  toolbutton 
)

Definition at line 1449 of file jobviewer.py.

01449 
01450     def on_refresh_clicked(self, toolbutton):
01451         self.monitor.refresh ()
01452         if self.my_monitor:
01453             self.my_monitor.refresh ()
01454 
01455         self.update_job_creation_times ()

Here is the call graph for this function:

def jobviewer.JobViewer.on_selection_changed (   self,
  selection 
)

Definition at line 1228 of file jobviewer.py.

01228 
01229     def on_selection_changed (self, selection):
01230         self.update_sensitivity (selection)

Here is the call graph for this function:

def jobviewer.JobViewer.on_show_completed_jobs_clicked (   self,
  toggletoolbutton 
)

Definition at line 707 of file jobviewer.py.

00707 
00708     def on_show_completed_jobs_clicked(self, toggletoolbutton):
00709         if toggletoolbutton.get_active():
00710             which_jobs = "all"
00711         else:
00712             which_jobs = "not-completed"
00713         self.monitor.refresh(which_jobs=which_jobs, refresh_all=False)
00714         if self.my_monitor:
00715             self.my_monitor.refresh(which_jobs=which_jobs, refresh_all=False)

def jobviewer.JobViewer.on_state_reason_notification_closed (   self,
  notification,
  reason = None 
)

Definition at line 1721 of file jobviewer.py.

01721 
01722     def on_state_reason_notification_closed (self, notification, reason=None):
01723         debugprint ("Notification %s closed" % repr (notification))
01724         notification.set_data ('closed', True)
01725         self.set_statusicon_visibility ()
01726         return

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.on_treeview_button_release_event (   self,
  treeview,
  event 
)

Definition at line 1131 of file jobviewer.py.

01131 
01132     def on_treeview_button_release_event(self, treeview, event):
01133         if event.button == 3:
01134             self.show_treeview_popup_menu (treeview, event, event.button)

Here is the call graph for this function:

def jobviewer.JobViewer.on_treeview_popup_menu (   self,
  treeview 
)

Definition at line 1127 of file jobviewer.py.

01127 
01128     def on_treeview_popup_menu (self, treeview):
01129         event = gtk.gdk.Event (gtk.gdk.NOTHING)
01130         self.show_treeview_popup_menu (treeview, event, 0)

Here is the call graph for this function:

def jobviewer.JobViewer.on_troubleshoot_quit (   self,
  troubleshooter 
)

Definition at line 785 of file jobviewer.py.

00785 
00786     def on_troubleshoot_quit(self, troubleshooter):
00787         del self.troubleshooter

Here is the caller graph for this function:

def jobviewer.JobViewer.poll_subprocess (   self,
  process 
)

Definition at line 1254 of file jobviewer.py.

01254 
01255     def poll_subprocess(self, process):
01256         returncode = process.poll ()
01257         return returncode == None

Here is the caller graph for this function:

def jobviewer.JobViewer.print_error_dialog_response (   self,
  dialog,
  response,
  jobid 
)

Definition at line 774 of file jobviewer.py.

00774 
00775     def print_error_dialog_response(self, dialog, response, jobid):
00776         dialog.hide ()
00777         dialog.destroy ()
00778         self.stopped_job_prompts.remove (jobid)
00779         if response == gtk.RESPONSE_NO:
00780             # Diagnose
00781             if not self.__dict__.has_key ('troubleshooter'):
00782                 import troubleshoot
00783                 troubleshooter = troubleshoot.run (self.on_troubleshoot_quit)
00784                 self.troubleshooter = troubleshooter

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.printer_added (   self,
  mon,
  printer 
)

Definition at line 2128 of file jobviewer.py.

02128 
02129     def printer_added (self, mon, printer):
02130         self.printer_uri_index.add_printer (printer)

Here is the caller graph for this function:

def jobviewer.JobViewer.printer_event (   self,
  mon,
  printer,
  eventname,
  event 
)

Definition at line 2131 of file jobviewer.py.

02131 
02132     def printer_event (self, mon, printer, eventname, event):
02133         self.printer_uri_index.update_from_attrs (printer, event)

Here is the caller graph for this function:

def jobviewer.JobViewer.printer_removed (   self,
  mon,
  printer 
)

Definition at line 2134 of file jobviewer.py.

02134 
02135     def printer_removed (self, mon, printer):
02136         self.printer_uri_index.remove_printer (printer)

Here is the caller graph for this function:

def jobviewer.JobViewer.set_process_pending (   self,
  whether 
)

Definition at line 650 of file jobviewer.py.

00650 
00651     def set_process_pending (self, whether):
00652         self.process_pending_events = whether

def jobviewer.JobViewer.set_statusicon_tooltip (   self,
  tooltip = None 
)

Definition at line 1595 of file jobviewer.py.

01595 
01596     def set_statusicon_tooltip (self, tooltip=None):
01597         if not self.applet:
01598             return
01599 
01600         if tooltip == None:
01601             num_jobs = len (self.jobs)
01602             if num_jobs == 0:
01603                 tooltip = _("No documents queued")
01604             elif num_jobs == 1:
01605                 tooltip = _("1 document queued")
01606             else:
01607                 tooltip = _("%d documents queued") % num_jobs
01608 
01609         self.statusicon.set_tooltip (tooltip)

Here is the caller graph for this function:

Definition at line 1091 of file jobviewer.py.

01091 
01092     def set_statusicon_visibility (self):
01093         if not self.applet:
01094             return
01095 
01096         if self.suppress_icon_hide:
01097             # Avoid hiding the icon if we've been woken up to notify
01098             # about a new printer.
01099             self.suppress_icon_hide = False
01100             return
01101 
01102         open_notifications = len (self.new_printer_notifications.keys ())
01103         open_notifications += len (self.completed_job_notifications.keys ())
01104         for reason, notification in self.state_reason_notifications.iteritems():
01105             if notification.get_data ('closed') != True:
01106                 open_notifications += 1
01107         num_jobs = len (self.active_jobs)
01108 
01109         debugprint ("open notifications: %d" % open_notifications)
01110         debugprint ("num_jobs: %d" % num_jobs)
01111         debugprint ("num_jobs_when_hidden: %d" % self.num_jobs_when_hidden)
01112 
01113         if self.notify_has_persistence:
01114             return
01115 
01116         # Don't handle tooltips during the mainloop recursion at the
01117         # end of this function as it seems to cause havoc (bug #664044,
01118         # bug #739745).
01119         self.statusicon.set_has_tooltip (False)
01120 
01121         self.statusicon.set_visible (open_notifications > 0 or
01122                                      num_jobs > self.num_jobs_when_hidden)
01123 
01124         # Let the icon show/hide itself before continuing.
01125         while self.process_pending_events and gtk.events_pending ():
01126             gtk.main_iteration ()

Here is the caller graph for this function:

def jobviewer.JobViewer.show_IPP_Error (   self,
  exception,
  message 
)

Definition at line 671 of file jobviewer.py.

00671 
00672     def show_IPP_Error(self, exception, message):
00673         return errordialogs.show_IPP_Error (exception, message, self.JobsWindow)

Here is the caller graph for this function:

def jobviewer.JobViewer.show_treeview_popup_menu (   self,
  treeview,
  event,
  event_button 
)

Definition at line 1231 of file jobviewer.py.

01231 
01232     def show_treeview_popup_menu (self, treeview, event, event_button):
01233         # Right-clicked.
01234         self.job_context_menu.popup (None, None, None, event_button,
01235                                      event.get_time ())

Here is the caller graph for this function:

def jobviewer.JobViewer.state_reason_added (   self,
  mon,
  reason 
)

Definition at line 2010 of file jobviewer.py.

02010 
02011     def state_reason_added (self, mon, reason):
02012         (title, text) = reason.get_description ()
02013         printer = reason.get_printer ()
02014 
02015         try:
02016             l = self.printer_state_reasons[printer]
02017         except KeyError:
02018             l = []
02019             self.printer_state_reasons[printer] = l
02020 
02021         reason.user_notified = False
02022         l.append (reason)
02023         self.update_status ()
02024         self.treeview.queue_draw ()
02025 
02026         if not self.applet:
02027             return
02028 
02029         # Find out if the user has jobs queued for that printer.
02030         for job, data in self.jobs.iteritems ():
02031             if not self.job_is_active (data):
02032                 continue
02033             if data['job-printer-name'] == printer:
02034                 # Yes!  Notify them of the state reason, if necessary.
02035                 self.notify_printer_state_reason_if_important (reason)
02036                 break

Here is the call graph for this function:

def jobviewer.JobViewer.state_reason_removed (   self,
  mon,
  reason 
)

Definition at line 2037 of file jobviewer.py.

02037 
02038     def state_reason_removed (self, mon, reason):
02039         printer = reason.get_printer ()
02040         try:
02041             reasons = self.printer_state_reasons[printer]
02042         except KeyError:
02043             debugprint ("Printer not found")
02044             return
02045 
02046         try:
02047             i = reasons.index (reason)
02048         except IndexError:
02049             debugprint ("Reason not found")
02050             return
02051 
02052         del reasons[i]
02053 
02054         self.update_status ()
02055         self.treeview.queue_draw ()
02056 
02057         if not self.applet:
02058             return
02059 
02060         tuple = reason.get_tuple ()
02061         try:
02062             notification = self.state_reason_notifications[tuple]
02063             if notification.get_data ('closed') != True:
02064                 try:
02065                     notification.close ()
02066                 except glib.GError:
02067                     # Can fail if the notification wasn't even shown
02068                     # yet (as in bug #545733).
02069                     pass
02070 
02071             del self.state_reason_notifications[tuple]
02072             self.set_statusicon_visibility ()
02073         except KeyError:
02074             pass

Here is the call graph for this function:

def jobviewer.JobViewer.still_connecting (   self,
  mon,
  reason 
)

Definition at line 2075 of file jobviewer.py.

02075 
02076     def still_connecting (self, mon, reason):
02077         if not self.applet:
02078             return
02079 
02080         self.notify_printer_state_reason (reason)

Here is the call graph for this function:

def jobviewer.JobViewer.toggle_window_display (   self,
  icon,
  force_show = False 
)

Definition at line 674 of file jobviewer.py.

00674 
00675     def toggle_window_display(self, icon, force_show=False):
00676         visible = self.JobsWindow.get_data('visible')
00677         if force_show:
00678             visible = False
00679 
00680         if self.notify_has_persistence:
00681             if visible:
00682                 self.JobsWindow.hide ()
00683             else:
00684                 self.JobsWindow.show ()
00685         else:
00686             if visible:
00687                 w = self.JobsWindow.window
00688                 aw = self.JobsAttributesWindow.window
00689                 (s, area, o) = self.statusicon.get_geometry ()
00690                 w.set_skip_taskbar_hint (True)
00691                 if aw != None:
00692                     aw.set_skip_taskbar_hint (True)
00693 
00694                 w.property_change ("_NET_WM_ICON_GEOMETRY",
00695                                    "CARDINAL", 32,
00696                                    gtk.gdk.PROP_MODE_REPLACE,
00697                                    list (area))
00698                 self.JobsWindow.iconify ()
00699             else:
00700                 self.JobsWindow.present ()
00701                 self.JobsWindow.window.set_skip_taskbar_hint (False)
00702                 aw = self.JobsAttributesWindow.window
00703                 if aw != None:
00704                     aw.set_skip_taskbar_hint (False)
00705 
00706         self.JobsWindow.set_data ('visible', not visible)

Here is the caller graph for this function:

def jobviewer.JobViewer.update_job (   self,
  job,
  data,
  connection = None 
)

Definition at line 826 of file jobviewer.py.

00826 
00827     def update_job (self, job, data, connection=None):
00828         # Fetch required attributes for this job if they are missing.
00829         r = self.required_job_attributes - set (data.keys ())
00830 
00831         # If we are showing attributes of this job at this moment, update them.
00832         if job in self.jobs_attrs:
00833             self.update_job_attributes_viewer(job)
00834 
00835         if r:
00836             attrs = None
00837             try:
00838                 if connection == None:
00839                     connection = cups.Connection (host=self.host,
00840                                                   port=self.port,
00841                                                   encryption=self.encryption)
00842 
00843                 debugprint ("requesting %s" % r)
00844                 r = list (r)
00845                 attrs = connection.getJobAttributes (job,
00846                                                      requested_attributes=r)
00847             except RuntimeError:
00848                 pass
00849             except AttributeError:
00850                 pass
00851             except cups.IPPError:
00852                 # someone else may have purged the job
00853                 return
00854 
00855             if attrs:
00856                 data.update (attrs)
00857 
00858         self.jobs[job] = data
00859 
00860         job_requires_auth = False
00861         try:
00862             jstate = data.get ('job-state', cups.IPP_JOB_PROCESSING)
00863             s = int (jstate)
00864 
00865             if s in [cups.IPP_JOB_HELD, cups.IPP_JOB_STOPPED]:
00866                 jattrs = ['job-state', 'job-hold-until']
00867                 pattrs = ['auth-info-required', 'device-uri']
00868                 uri = data.get ('job-printer-uri')
00869                 c = authconn.Connection (self.JobsWindow,
00870                                          host=self.host,
00871                                          port=self.port,
00872                                          encryption=self.encryption)
00873                 attrs = c.getPrinterAttributes (uri = uri,
00874                                                 requested_attributes=pattrs)
00875 
00876                 try:
00877                     auth_info_required = attrs['auth-info-required']
00878                 except KeyError:
00879                     debugprint ("No auth-info-required attribute; "
00880                                 "guessing instead")
00881                     auth_info_required = ['username', 'password']
00882 
00883                 if not isinstance (auth_info_required, list):
00884                     auth_info_required = [auth_info_required]
00885                     attrs['auth-info-required'] = auth_info_required
00886 
00887                 data.update (attrs)
00888 
00889                 attrs = c.getJobAttributes (job,
00890                                             requested_attributes=jattrs)
00891                 data.update (attrs)
00892                 jstate = data.get ('job-state', cups.IPP_JOB_PROCESSING)
00893                 s = int (jstate)
00894         except ValueError:
00895             pass
00896         except RuntimeError:
00897             pass
00898         except cups.IPPError, (e, m):
00899             pass
00900 
00901         # Invalidate the cached status description and redraw the treeview.
00902         try:
00903             del data['_status_text']
00904         except KeyError:
00905             pass
00906         self.treeview.queue_draw ()
00907 
00908         # Check whether authentication is required.
00909         if self.applet:
00910             job_requires_auth = (s == cups.IPP_JOB_HELD and
00911                                  data.get ('job-hold-until', 'none') ==
00912                                  'auth-info-required')
00913 
00914             if (job_requires_auth and
00915                 not self.auth_info_dialogs.has_key (job)):
00916                 try:
00917                     cups.require ("1.9.37")
00918                 except:
00919                     debugprint ("Authentication required but "
00920                                 "authenticateJob() not available")
00921                     return
00922 
00923                 # Find out which auth-info is required.
00924                 try_keyring = USE_KEYRING
00925                 keyring_attrs = dict()
00926                 auth_info = None
00927                 if try_keyring and 'password' in auth_info_required:
00928                     auth_info_required = data.get ('auth-info-required', [])
00929                     device_uri = data.get ("device-uri")
00930                     (scheme, rest) = urllib.splittype (device_uri)
00931                     if scheme == 'smb':
00932                         uri = smburi.SMBURI (uri=device_uri)
00933                         (group, server, share,
00934                          user, password) = uri.separate ()
00935                         keyring_attrs["domain"] = str (group)
00936                     else:
00937                         (serverport, rest) = urllib.splithost (rest)
00938                         (server, port) = urllib.splitnport (serverport)
00939                     keyring_attrs.update ({ "server": str (server.lower ()),
00940                                             "protocol": str (scheme)})
00941 
00942                 if job in self.authenticated_jobs:
00943                     # We've already tried to authenticate this job before.
00944                     try_keyring = False
00945 
00946                 if try_keyring and 'password' in auth_info_required:
00947                     type = gnomekeyring.ITEM_NETWORK_PASSWORD
00948                     try:
00949                         items = gnomekeyring.find_items_sync (type,
00950                                                               keyring_attrs)
00951                         auth_info = map (lambda x: '', auth_info_required)
00952                         ind = auth_info_required.index ('username')
00953                         auth_info[ind] = items[0].attributes.get ('user', '')
00954                         ind = auth_info_required.index ('password')
00955                         auth_info[ind] = items[0].secret
00956                     except gnomekeyring.NoMatchError:
00957                         debugprint ("gnomekeyring: no match for %s" %
00958                                     keyring_attrs)
00959                     except gnomekeyring.DeniedError:
00960                         debugprint ("gnomekeyring: denied for %s" %
00961                                     keyring_attrs)
00962 
00963                 if try_keyring and c == None:
00964                     try:
00965                         c = authconn.Connection (self.JobsWindow,
00966                                                  host=self.host,
00967                                                  port=self.port,
00968                                                  encryption=self.encryption)
00969                     except RuntimeError:
00970                         try_keyring = False
00971 
00972                 if try_keyring and auth_info != None:
00973                     try:
00974                         c._begin_operation (_("authenticating job"))
00975                         c.authenticateJob (job, auth_info)
00976                         c._end_operation ()
00977                         self.update_monitor ()
00978                         debugprint ("Automatically authenticated job %d" % job)
00979                         self.authenticated_jobs.add (job)
00980                         return
00981                     except cups.IPPError, (e, m):
00982                         c._end_operation ()
00983                         nonfatalException ()
00984                         return
00985                     except:
00986                         c._end_operation ()
00987                         nonfatalException ()
00988 
00989                 username = pwd.getpwuid (os.getuid ())[0]
00990                 keyring_attrs["user"] = str (username)
00991                 self.display_auth_info_dialog (job, keyring_attrs)
00992         self.update_sensitivity ()

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.update_job_attributes_viewer (   self,
  jobid,
  conn = None 
)
Update attributes store with new values. 

Definition at line 1489 of file jobviewer.py.

01489 
01490     def update_job_attributes_viewer(self, jobid, conn=None):
01491         """ Update attributes store with new values. """
01492         if conn != None:
01493             c = conn
01494         else:
01495             try:
01496                 c = cups.Connection (host=self.host,
01497                                      port=self.port,
01498                                      encryption=self.encryption)
01499             except RuntimeError:
01500                 return False
01501 
01502         if jobid in self.jobs_attrs:
01503             (attr_store, page) = self.jobs_attrs[jobid]
01504             try:
01505                 attrs = c.getJobAttributes(jobid)       # new attributes
01506             except AttributeError:
01507                 return
01508             except cups.IPPError:
01509                 # someone else may have purged the job,
01510                 # remove jobs notebook page
01511                 self.notebook.remove_page(page)
01512                 del self.jobs_attrs[jobid]
01513                 return
01514 
01515             attr_store.clear()                          # remove old attributes
01516             for name, value in attrs.iteritems():
01517                 if name in ['job-id', 'job-printer-up-time']:
01518                     continue
01519                 attr_store.append([name, str(value)])

Here is the caller graph for this function:

Definition at line 716 of file jobviewer.py.

00716 
00717     def update_job_creation_times(self):
00718         now = time.time ()
00719         need_update = False
00720         for job, data in self.jobs.iteritems():
00721             t = _("Unknown")
00722             if data.has_key ('time-at-creation'):
00723                 created = data['time-at-creation']
00724                 ago = now - created
00725                 need_update = True
00726                 if ago < 2 * 60:
00727                     t = _("a minute ago")
00728                 elif ago < 60 * 60:
00729                     mins = int (ago / 60)
00730                     t = _("%d minutes ago") % mins
00731                 elif ago < 24 * 60 * 60:
00732                     hours = int (ago / (60 * 60))
00733                     if hours == 1:
00734                         t = _("an hour ago")
00735                     else:
00736                         t = _("%d hours ago") % hours
00737                 elif ago < 7 * 24 * 60 * 60:
00738                     days = int (ago / (24 * 60 * 60))
00739                     if days == 1:
00740                         t = _("yesterday")
00741                     else:
00742                         t = _("%d days ago") % days
00743                 elif ago < 6 * 7 * 24 * 60 * 60:
00744                     weeks = int (ago / (7 * 24 * 60 * 60))
00745                     if weeks == 1:
00746                         t = _("last week")
00747                     else:
00748                         t = _("%d weeks ago") % weeks
00749                 else:
00750                     need_update = False
00751                     t = time.strftime ("%B %Y", time.localtime (created))
00752 
00753             if self.jobiters.has_key (job):
00754                 iter = self.jobiters[job]
00755                 self.store.set_value (iter, 1, t)
00756 
00757         if need_update and not self.job_creation_times_timer:
00758             def update_times_with_locking ():
00759                 gtk.gdk.threads_enter ()
00760                 ret = self.update_job_creation_times ()
00761                 gtk.gdk.threads_leave ()
00762                 return ret
00763 
00764             t = gobject.timeout_add_seconds (60, update_times_with_locking)
00765             self.job_creation_times_timer = t
00766 
00767         if not need_update:
00768             if self.job_creation_times_timer:
00769                 gobject.source_remove (self.job_creation_times_timer)
00770                 self.job_creation_times_timer = None
00771 
00772         # Return code controls whether the timeout will recur.
00773         return need_update

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 821 of file jobviewer.py.

00821 
00822     def update_monitor (self):
00823         self.monitor.update ()
00824         if self.my_monitor:
00825             self.my_monitor.update ()

Here is the caller graph for this function:

def jobviewer.JobViewer.update_sensitivity (   self,
  selection = None 
)

Definition at line 1135 of file jobviewer.py.

01135 
01136     def update_sensitivity (self, selection = None):
01137         if (selection is None):
01138             selection = self.treeview.get_selection () 
01139         (model, pathlist) = selection.get_selected_rows()
01140         cancel = self.job_ui_manager.get_action ("/cancel-job")
01141         delete = self.job_ui_manager.get_action ("/delete-job")
01142         hold = self.job_ui_manager.get_action ("/hold-job")
01143         release = self.job_ui_manager.get_action ("/release-job")
01144         reprint = self.job_ui_manager.get_action ("/reprint-job")
01145         retrieve = self.job_ui_manager.get_action ("/retrieve-job")
01146         authenticate = self.job_ui_manager.get_action ("/authenticate-job")
01147         attributes = self.job_ui_manager.get_action ("/job-attributes")
01148         move = self.job_ui_manager.get_action ("/move-job")
01149         if len (pathlist) == 0:
01150             for widget in [cancel, delete, hold, release, reprint, retrieve,
01151                            move, authenticate, attributes]:
01152                 widget.set_sensitive (False)
01153             return
01154 
01155         cancel_sensitive = True
01156         hold_sensitive = True
01157         release_sensitive = True
01158         reprint_sensitive = True
01159         authenticate_sensitive = True
01160         move_sensitive = False
01161         other_printers = self.printer_uri_index.all_printer_names ()
01162         job_printers = dict()
01163 
01164         self.jobids = []
01165         for path in pathlist:
01166             iter = self.store.get_iter (path)
01167             jobid = self.store.get_value (iter, 0)
01168             self.jobids.append(jobid)
01169             job = self.jobs[jobid]
01170 
01171             if job.has_key ('job-state'):
01172                 s = job['job-state']
01173                 if s >= cups.IPP_JOB_CANCELED:
01174                     cancel_sensitive = False
01175                 if s != cups.IPP_JOB_PENDING:
01176                     hold_sensitive = False
01177                 if s != cups.IPP_JOB_HELD:
01178                     release_sensitive = False
01179                 if (not job.get('job-preserved', False)):
01180                     reprint_sensitive = False
01181 
01182             if (job.get ('job-state',
01183                          cups.IPP_JOB_CANCELED) != cups.IPP_JOB_HELD or
01184                 job.get ('job-hold-until', 'none') != 'auth-info-required'):
01185                 authenticate_sensitive = False
01186 
01187             uri = job.get ('job-printer-uri', None)
01188             if uri:
01189                 try:
01190                     printer = self.printer_uri_index.lookup (uri)
01191                 except KeyError:
01192                     printer = uri
01193                 job_printers[printer] = uri
01194 
01195         if len (job_printers.keys ()) == 1:
01196             try:
01197                 other_printers.remove (job_printers.keys ()[0])
01198             except KeyError:
01199                 pass
01200 
01201         if len (other_printers) > 0:
01202             printers_menu = gtk.Menu ()
01203             other_printers = list (other_printers)
01204             other_printers.sort ()
01205             for printer in other_printers:
01206                 try:
01207                     uri = self.printer_uri_index.lookup_cached_by_name (printer)
01208                 except KeyError:
01209                     uri = None
01210                 menuitem = gtk.MenuItem (printer, False)
01211                 menuitem.set_sensitive (uri != None)
01212                 menuitem.show ()
01213                 menuitem.connect ('activate', self.on_job_move_activate, uri)
01214                 printers_menu.append (menuitem)
01215 
01216             self.move_job_menuitem.set_submenu (printers_menu)
01217             move_sensitive = True
01218 
01219         cancel.set_sensitive(cancel_sensitive)
01220         delete.set_sensitive(not cancel_sensitive)
01221         hold.set_sensitive(hold_sensitive)
01222         release.set_sensitive(release_sensitive)
01223         reprint.set_sensitive(reprint_sensitive)
01224         retrieve.set_sensitive(reprint_sensitive)
01225         move.set_sensitive (move_sensitive)
01226         authenticate.set_sensitive(authenticate_sensitive)
01227         attributes.set_sensitive(True)

Here is the call graph for this function:

Here is the caller graph for this function:

def jobviewer.JobViewer.update_status (   self,
  have_jobs = None 
)

Definition at line 1610 of file jobviewer.py.

01610 
01611     def update_status (self, have_jobs=None):
01612         # Found out which printer state reasons apply to our active jobs.
01613         upset_printers = set()
01614         for printer, reasons in self.printer_state_reasons.iteritems ():
01615             if len (reasons) > 0:
01616                 upset_printers.add (printer)
01617         debugprint ("Upset printers: %s" % upset_printers)
01618 
01619         my_upset_printers = set()
01620         if len (upset_printers):
01621             my_upset_printers = set()
01622             for jobid in self.active_jobs:
01623                 # 'job-printer-name' is set by job_added/job_event
01624                 printer = self.jobs[jobid]['job-printer-name']
01625                 if printer in upset_printers:
01626                     my_upset_printers.add (printer)
01627             debugprint ("My upset printers: %s" % my_upset_printers)
01628 
01629         my_reasons = []
01630         for printer in my_upset_printers:
01631             my_reasons.extend (self.printer_state_reasons[printer])
01632 
01633         # Find out which is the most problematic.
01634         self.worst_reason = None
01635         if len (my_reasons) > 0:
01636             worst_reason = my_reasons[0]
01637             for reason in my_reasons:
01638                 if reason > worst_reason:
01639                     worst_reason = reason
01640             self.worst_reason = worst_reason
01641             debugprint ("Worst reason: %s" % worst_reason)
01642 
01643         self.statusbar.pop (0)
01644         if self.worst_reason != None:
01645             (title, tooltip) = self.worst_reason.get_description ()
01646             self.statusbar.push (0, tooltip)
01647         else:
01648             tooltip = None
01649             status_message = ""
01650             processing = 0
01651             pending = 0
01652             for jobid in self.active_jobs:
01653                 try:
01654                     job_state = self.jobs[jobid]['job-state']
01655                 except KeyError:
01656                     continue
01657                 if job_state == cups.IPP_JOB_PROCESSING:
01658                     processing = processing + 1
01659                 elif job_state == cups.IPP_JOB_PENDING:
01660                     pending = pending + 1
01661             if ((processing > 0) or (pending > 0)):
01662                 status_message = _("processing / pending:   %d / %d") % (processing, pending)
01663                 self.statusbar.push(0, status_message)
01664 
01665         if self.applet and not self.notify_has_persistence:
01666             pixbuf = self.get_icon_pixbuf (have_jobs=have_jobs)
01667             self.statusicon.set_from_pixbuf (pixbuf)
01668             self.set_statusicon_visibility ()
01669             self.set_statusicon_tooltip (tooltip=tooltip)

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

dictionary jobviewer.JobViewer.__gsignals__ [static, private]
Initial value:
{
        'finished':    (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [])
        }

Definition at line 321 of file jobviewer.py.

Definition at line 343 of file jobviewer.py.

Definition at line 331 of file jobviewer.py.

Definition at line 596 of file jobviewer.py.

Definition at line 349 of file jobviewer.py.

Definition at line 353 of file jobviewer.py.

Definition at line 352 of file jobviewer.py.

Definition at line 347 of file jobviewer.py.

Definition at line 554 of file jobviewer.py.

Definition at line 552 of file jobviewer.py.

Definition at line 528 of file jobviewer.py.

Definition at line 529 of file jobviewer.py.

Definition at line 530 of file jobviewer.py.

Definition at line 408 of file jobviewer.py.

Definition at line 350 of file jobviewer.py.

Definition at line 388 of file jobviewer.py.

Definition at line 341 of file jobviewer.py.

Definition at line 340 of file jobviewer.py.

Definition at line 339 of file jobviewer.py.

Definition at line 342 of file jobviewer.py.

Definition at line 583 of file jobviewer.py.

Definition at line 330 of file jobviewer.py.

Definition at line 555 of file jobviewer.py.

Definition at line 427 of file jobviewer.py.

Definition at line 333 of file jobviewer.py.

Definition at line 571 of file jobviewer.py.

Definition at line 351 of file jobviewer.py.

Definition at line 615 of file jobviewer.py.

Definition at line 336 of file jobviewer.py.

Definition at line 337 of file jobviewer.py.

Definition at line 346 of file jobviewer.py.

Definition at line 354 of file jobviewer.py.

Definition at line 553 of file jobviewer.py.

Definition at line 345 of file jobviewer.py.

Definition at line 1787 of file jobviewer.py.

Definition at line 651 of file jobviewer.py.

Initial value:
set(['job-k-octets',
                                   'job-name',
                                   'job-originating-user-name',
                                   'job-printer-uri',
                                   'job-state',
                                   'time-at-creation',
                                   'job-preserved'])

Definition at line 313 of file jobviewer.py.

Definition at line 488 of file jobviewer.py.

Definition at line 334 of file jobviewer.py.

Definition at line 348 of file jobviewer.py.

Definition at line 541 of file jobviewer.py.

Definition at line 344 of file jobviewer.py.

Definition at line 484 of file jobviewer.py.

Definition at line 332 of file jobviewer.py.

Definition at line 783 of file jobviewer.py.

Definition at line 1539 of file jobviewer.py.


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