1 # -*- coding: utf-8 -*-
3 # (c) Copyright 2001-2009 Hewlett-Packard Development Company, L.P.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # Authors: Don Welch, Pete Parks, Naga Samrat Chowdary Narla,
22 from __future__ import generators
36 from base import device, utils, pml, maint, pkit
38 from base.codes import *
39 from ui_utils import load_pixmap
40 from installer.core_install import *
46 from devmgr4_base import DevMgr4_base
49 from scrollview import ScrollView
50 from scrollprintsettings import ScrollPrintSettingsView
52 # Alignment and ColorCal forms
53 from alignform import AlignForm
54 from aligntype6form1 import AlignType6Form1
55 from aligntype6form2 import AlignType6Form2
56 from paperedgealignform import PaperEdgeAlignForm
57 from colorcalform import ColorCalForm # Type 1 color cal
58 from coloradjform import ColorAdjForm # Type 5 and 6 color adj
59 from colorcalform2 import ColorCalForm2 # Type 2 color cal
60 from colorcal4form import ColorCal4Form # Type 4 color cal
61 from align10form import Align10Form # Type 10 and 11 alignment
62 from align13form import Align13Form # Type 13 alignment
65 from loadpaperform import LoadPaperForm
66 from settingsdialog import SettingsDialog
67 from aboutdlg import AboutDlg
68 from cleaningform import CleaningForm
69 from cleaningform2 import CleaningForm2
70 from waitform import WaitForm
71 from faxsettingsform import FaxSettingsForm
72 from nodevicesform import NoDevicesForm
73 from settingsdialog import SettingsDialog
74 from firmwaredialog import FirmwareDialog
77 MIN_AUTO_REFRESH_RATE = 5
78 MAX_AUTO_REFRESH_RATE = 60
79 DEF_AUTO_REFRESH_RATE = 30
82 devices = {} # { Device_URI : device.Device(), ... }
83 devices_lock = threading.RLock()
88 # ***********************************************************************************
90 # LISTVIEW/UTILITY UI CLASSES
92 # ***********************************************************************************
94 class IconViewToolTip(QToolTip):
95 def __init__(self, parent, tooltip_text):
96 QToolTip.__init__(self, parent.viewport())
100 def maybeTip(self, pos):
101 abs_coords = QPoint(pos.x() + self.parent.contentsX(),
102 pos.y() + self.parent.contentsY())
104 item = self.parent.findItem(abs_coords)
106 if item is not None and item.tooltip_text:
108 rel_coords.setX(pos.x())
109 rel_coords.setY(pos.y())
111 rel_coords.setWidth(i.width())
112 rel_coords.setHeight(i.height())
113 self.tip(rel_coords, item.tooltip_text)
117 class FuncViewItem(QIconViewItem):
118 def __init__(self, parent, text, pixmap, tooltip_text, cmd):
119 QIconViewItem.__init__(self, parent, text, pixmap)
120 self.tooltip_text = tooltip_text
123 self.tooltip = IconViewToolTip(parent, tooltip_text)
127 class DeviceViewItem(QIconViewItem):
128 def __init__(self, parent, text, pixmap, device_uri, is_avail=True):
129 QIconViewItem.__init__(self, parent, text, pixmap)
130 self.device_uri = device_uri
131 self.is_avail = is_avail
135 class SuppliesListViewItem(QListViewItem):
136 def __init__(self, parent, pixmap, desc, part_no, level_pixmap, status):
137 QListViewItem.__init__(self, parent, '', desc, part_no, '', status)
138 if pixmap is not None:
139 self.setPixmap(0, pixmap)
140 if level_pixmap is not None:
141 self.setPixmap(3, level_pixmap)
143 def paintCell(self, p, cg, c, w, a):
144 color = QColorGroup(cg)
145 pos = self.listView().itemPos(self)
146 h = self.totalHeight()
149 color.setColor(QColorGroup.Base, QColor(220, 228, 249))
151 QListViewItem.paintCell(self, p, color, c, w, a)
155 class PasswordDialog(QDialog):
156 def __init__(self,prompt, parent=None, name=None, modal=0, fl=0):
157 QDialog.__init__(self,parent,name,modal,fl)
161 self.setName("PasswordDialog")
163 passwordDlg_baseLayout = QGridLayout(self,1,1,11,6,"passwordDlg_baseLayout")
165 self.promptTextLabel = QLabel(self,"promptTextLabel")
166 passwordDlg_baseLayout.addMultiCellWidget(self.promptTextLabel,0,0,0,1)
168 self.usernameTextLabel = QLabel(self,"usernameTextLabel")
169 passwordDlg_baseLayout.addMultiCellWidget(self.usernameTextLabel,1,1,0,1)
171 self.usernameLineEdit = QLineEdit(self,"usernameLineEdit")
172 self.usernameLineEdit.setEchoMode(QLineEdit.Normal)
173 passwordDlg_baseLayout.addMultiCellWidget(self.usernameLineEdit,1,1,1,2)
175 self.passwordTextLabel = QLabel(self,"passwordTextLabel")
176 passwordDlg_baseLayout.addMultiCellWidget(self.passwordTextLabel,2,2,0,1)
178 self.passwordLineEdit = QLineEdit(self,"passwordLineEdit")
179 self.passwordLineEdit.setEchoMode(QLineEdit.Password)
180 passwordDlg_baseLayout.addMultiCellWidget(self.passwordLineEdit,2,2,1,2)
182 self.okPushButton = QPushButton(self,"okPushButton")
183 passwordDlg_baseLayout.addWidget(self.okPushButton,3,2)
185 self.languageChange()
187 self.resize(QSize(420,163).expandedTo(self.minimumSizeHint()))
188 self.clearWState(Qt.WState_Polished)
190 self.connect(self.okPushButton,SIGNAL("clicked()"),self.accept)
191 self.connect(self.passwordLineEdit,SIGNAL("returnPressed()"),self.accept)
192 def getUsername(self):
193 return unicode(self.usernameLineEdit.text())
195 def getPassword(self):
196 return unicode(self.passwordLineEdit.text())
198 def languageChange(self):
199 self.setCaption(self.__tr("HP Device Manager - Enter Username/Password"))
200 self.promptTextLabel.setText(self.__tr(self.prompt))
201 self.usernameTextLabel.setText(self.__tr("Username"))
202 self.passwordTextLabel.setText(self.__tr("Password"))
203 self.okPushButton.setText(self.__tr("OK"))
205 def __tr(self,s,c = None):
206 return qApp.translate("PasswordDialog",s,c)
210 class ScrollDialog(QDialog):
211 def __init__(self, scrollview_cls, cur_device, cur_printer, service,
212 parent = None, name=None, modal=0, fl=0):
214 QDialog.__init__(self,parent,name,modal,fl)
217 self.setName("ScrollDialog")
219 self.setSizeGripEnabled(1)
220 ScrollDialogLayout = QGridLayout(self,1,1,11,6,"ScrollDialogLayout")
221 Layout1 = QHBoxLayout(None,0,6,"Layout1")
222 Horizontal_Spacing2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
223 Layout1.addItem(Horizontal_Spacing2)
224 self.buttonOk = QPushButton(self,"buttonOk")
225 self.buttonOk.setAutoDefault(1)
226 self.buttonOk.setDefault(1)
227 Layout1.addWidget(self.buttonOk)
228 ScrollDialogLayout.addLayout(Layout1,1,0)
230 self.scrollview = scrollview_cls(service, self)
231 ScrollDialogLayout.addWidget(self.scrollview,0,0)
233 self.scrollview.onDeviceChange(cur_device)
234 self.scrollview.onPrinterChange(cur_printer)
235 self.languageChange()
237 self.resize(QSize(520,457).expandedTo(self.minimumSizeHint()))
238 self.clearWState(Qt.WState_Polished)
239 self.connect(self.buttonOk,SIGNAL("clicked()"),self.accept)
242 def languageChange(self):
243 self.setCaption(self.__tr("HP Device Manager"))
244 self.buttonOk.setText(self.__tr("Close"))
245 self.buttonOk.setAccel(QKeySequence(QString.null))
247 def __tr(self,s,c = None):
248 return qApp.translate("ScrollDialog",s,c)
251 def showPasswordUI(prompt):
253 dlg = PasswordDialog(prompt, None)
255 if dlg.exec_loop() == QDialog.Accepted:
256 return (dlg.getUsername(), dlg.getPassword())
264 class StatusListViewItem(QListViewItem):
265 def __init__(self, parent, pixmap, ess, tt, event_code, job_id, username):
266 QListViewItem.__init__(self, parent, '', ess, tt, event_code, job_id, username)
267 self.setPixmap(0, pixmap)
269 def paintCell(self, p, cg, c, w, a):
270 color = QColorGroup(cg)
271 pos = self.listView().itemPos(self)
272 h = self.totalHeight()
276 color.setColor(QColorGroup.Base, QColor(220, 228, 249))
278 QListViewItem.paintCell(self, p, color, c, w, a)
282 class JobListViewItem(QCheckListItem):
283 def __init__(self, parent, pixmap, desc, status, job_id):
284 QCheckListItem.__init__(self, parent, '', QCheckListItem.CheckBox)
286 self.setPixmap(1, pixmap)
287 self.setText(2, desc)
288 self.setText(3, status)
289 self.setText(4, job_id)
291 def paintCell(self, p, cg, c, w, a):
292 color = QColorGroup(cg)
293 pos = self.listView().itemPos(self)
294 h = self.totalHeight()
297 color.setColor(QColorGroup.Base, QColor(220, 228, 249))
299 QCheckListItem.paintCell(self, p, color, c, w, a)
303 class JobInfoDialog(QDialog):
304 def __init__(self, text, parent=None, name=None, modal=0, fl=0):
305 QDialog.__init__(self, parent, name, modal, fl)
308 self.setName("JobInfoDialog")
310 Form1Layout = QGridLayout(self,1,1,11,6,"Form1Layout")
311 spacer6 = QSpacerItem(371,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
312 Form1Layout.addItem(spacer6,1,0)
313 self.pushButton4 = QPushButton(self,"pushButton4")
314 Form1Layout.addWidget(self.pushButton4,1,1)
315 self.textEdit = QTextEdit(self,"textEdit")
316 Form1Layout.addMultiCellWidget(self.textEdit,0,0,0,1)
318 self.languageChange()
320 self.resize(QSize(571,542).expandedTo(self.minimumSizeHint()))
321 self.clearWState(Qt.WState_Polished)
323 self.connect(self.pushButton4,SIGNAL("clicked()"),self.close)
325 self.textEdit.setText(text)
328 def languageChange(self):
329 self.setCaption(self.__tr("HP Device Manager - Job Log"))
330 self.pushButton4.setText(self.__tr("Close"))
333 def __tr(self,s,c = None):
334 return qApp.translate("JobInfoDialog",s,c)
337 # ***********************************************************************************
339 # DEVICE UPDATE THREAD
341 # ***********************************************************************************
344 class UpdateThread(QThread):
345 def __init__(self, response_queue=None, request_queue=None):
346 self.response_queue = response_queue # update queue -> main window
347 self.request_queue = request_queue # main window -> update queue
349 QThread.__init__(self)
353 dev = self.request_queue.get(True)
356 log.debug("Update thread: exit")
359 log.debug("Update thread start: %s" % dev.device_uri)
362 #print "THREAD LOCK ACQUIRE"
363 devices_lock.acquire()
364 #print "THREAD LOCK ACQUIRE - OK"
365 self.response_queue.put((RESPONSE_START, dev.device_uri))
366 log.debug(log.bold("Update: %s %s %s" % ("*"*20, dev.device_uri, "*"*20)))
376 if dev.device_state == DEVICE_STATE_NOT_FOUND:
377 dev.error_state = ERROR_STATE_ERROR
383 log.error("Query device error (%s)." % e.msg)
384 dev.error_state = ERROR_STATE_ERROR
388 #print "THREAD LOCK RELEASE"
389 devices_lock.release()
391 log.debug("Device state = %d" % dev.device_state)
392 log.debug("Status code = %d" % dev.status_code)
393 log.debug("Error state = %d" % dev.error_state)
395 log.debug("Update thread end: %s" % dev.device_uri)
397 self.response_queue.put((RESPONSE_DONE, dev.device_uri))
400 # ***********************************************************************************
404 # ***********************************************************************************
406 class DevMgr4(DevMgr4_base):
407 def __init__(self, read_pipe=None, toolbox_version='0.0',
408 initial_device_uri=None, disable_dbus=False,
409 parent=None, name=None, fl = 0):
412 # Distro insformation
413 core = CoreInstall(MODE_CHECK)
415 self.Is_autoInstaller_distro = core.is_auto_installer_support()
416 self.Latest_ver= user_conf.get('upgrade', 'latest_available_version')
417 installed_version=sys_conf.get('hplip','version')
418 if utils.Is_HPLIP_older_version(installed_version, self.Latest_ver):
419 DevMgr4_base.__init__(self, parent, name, fl,self.Latest_ver,self.Is_autoInstaller_distro)
422 DevMgr4_base.__init__(self, parent, name, fl,self.Latest_ver,self.Is_autoInstaller_distro)
423 log.debug("Initializing toolbox UI (Qt3)...")
424 log.debug("HPLIP Version: %s" % prop.installed_version)
426 self.disable_dbus = disable_dbus
427 self.toolbox_version = toolbox_version
428 self.cur_device_uri = user_conf.get('last_used', 'device_uri')
429 self.device_vars = {}
431 self.cur_device = None
432 self.rescanning = False
433 self.initial_device_uri = initial_device_uri
436 if not self.disable_dbus:
437 self.dbus_avail, self.service, session_bus = device.init_dbus()
439 if not self.dbus_avail:
440 self.FailureUI("<b>Error</b><p>hp-systray must be running to get device status. hp-systray requires dbus support. Device status will not be available.")
442 log.debug("dbus enabled")
445 log.debug("dbus disabled")
446 self.dbus_avail, self.service = False, None
449 # Update thread setup
450 self.request_queue = Queue.Queue()
451 self.response_queue = Queue.Queue()
452 self.update_thread = UpdateThread(self.response_queue, self.request_queue)
453 self.update_thread.start()
455 # Pipe from toolbox/dbus setup
456 self.fmt = "80s80sI32sI80sf"
457 self.fmt_size = struct.calcsize(self.fmt)
459 if read_pipe is not None and not disable_dbus:
460 log.debug("Setting up read_pipe")
461 self.notifier = QSocketNotifier(read_pipe, QSocketNotifier.Read)
462 QObject.connect(self.notifier, SIGNAL("activated(int)"), self.notifier_activated)
465 self.setIcon(load_pixmap('hp_logo', '128x128'))
468 self.user_settings = utils.UserSettings()
469 self.cmd_fab = self.user_settings.cmd_fab
470 log.debug("FAB command: %s" % self.cmd_fab)
472 if not self.user_settings.auto_refresh:
473 self.autoRefresh.toggle()
475 # Other initialization
480 cups.setPasswordCallback(showPasswordUI)
482 if not prop.doc_build:
483 self.helpContentsAction.setEnabled(False)
485 self.allow_auto_refresh = True
486 QTimer.singleShot(0, self.InitialUpdate)
489 # ***********************************************************************************
493 # ***********************************************************************************
495 def InitPixmaps(self):
496 self.func_icons_cached = False
498 self.device_icons = {}
500 # TODO: Use Qt pixmap cache for all pixmaps?
502 # Device icon list overlays
503 self.warning_pix = load_pixmap('warning', '16x16')
504 self.error_pix = load_pixmap('error', '16x16')
505 self.ok_pix = load_pixmap('ok', '16x16')
506 self.lowink_pix = load_pixmap('inkdrop', '16x16')
507 self.lowtoner_pix = load_pixmap('toner', '16x16')
508 self.busy_pix = load_pixmap('busy', '16x16')
509 self.lowpaper_pix = load_pixmap('paper', '16x16')
510 self.refresh_pix = load_pixmap('refresh', '16x16')
511 self.refresh1_pix = load_pixmap('refresh1', '16x16')
512 self.fax_icon = load_pixmap('fax2', 'other')
513 self.idle_pix = load_pixmap('idle', '16x16')
514 self.scan_pix = load_pixmap("scan", '16x16')
515 self.print_pix = load_pixmap("print", '16x16')
516 self.sendfax_pix =load_pixmap("fax", '16x16')
517 self.pcard_pix = load_pixmap("pcard", '16x16')
518 self.makecopies_pix = load_pixmap("makecopies", '16x16')
519 self.help_pix = load_pixmap("help", '16x16')
522 # pixmaps: (inkjet, laserjet)
523 self.SMALL_ICONS = { ERROR_STATE_CLEAR : (None, None),
524 ERROR_STATE_BUSY : (self.busy_pix, self.busy_pix),
525 ERROR_STATE_ERROR : (self.error_pix, self.error_pix),
526 ERROR_STATE_LOW_SUPPLIES : (self.lowink_pix, self.lowtoner_pix),
527 ERROR_STATE_OK : (self.ok_pix, self.ok_pix),
528 ERROR_STATE_WARNING : (self.warning_pix, self.warning_pix),
529 ERROR_STATE_LOW_PAPER: (self.lowpaper_pix, self.lowpaper_pix),
530 ERROR_STATE_PRINTING : (self.busy_pix, self.busy_pix),
531 ERROR_STATE_SCANNING : (self.busy_pix, self.busy_pix),
532 ERROR_STATE_PHOTOCARD : (self.busy_pix, self.busy_pix),
533 ERROR_STATE_FAXING : (self.busy_pix, self.busy_pix),
534 ERROR_STATE_COPYING : (self.busy_pix, self.busy_pix),
535 ERROR_STATE_REFRESHING : (self.refresh1_pix, self.refresh1_pix),
538 self.STATUS_ICONS = { ERROR_STATE_CLEAR : (self.idle_pix, self.idle_pix),
539 ERROR_STATE_BUSY : (self.busy_pix, self.busy_pix),
540 ERROR_STATE_ERROR : (self.error_pix, self.error_pix),
541 ERROR_STATE_LOW_SUPPLIES : (self.lowink_pix, self.lowtoner_pix),
542 ERROR_STATE_OK : (self.ok_pix, self.ok_pix),
543 ERROR_STATE_WARNING : (self.warning_pix, self.warning_pix),
544 ERROR_STATE_LOW_PAPER: (self.lowpaper_pix, self.lowpaper_pix),
545 ERROR_STATE_PRINTING : (self.print_pix, self.print_pix),
546 ERROR_STATE_SCANNING : (self.scan_pix, self.scan_pix),
547 ERROR_STATE_PHOTOCARD : (self.pcard_pix, self.print_pix),
548 ERROR_STATE_FAXING : (self.sendfax_pix, self.sendfax_pix),
549 ERROR_STATE_COPYING : (self.makecopies_pix, self.makecopies_pix),
555 # Setup device icon list
556 self.DeviceList.setAutoArrange(True)
557 self.DeviceList.setSorting(True)
560 self.deviceRescanAction.setIconSet(QIconSet(self.refresh1_pix))
561 self.deviceRefreshAll.setIconSet(QIconSet(self.refresh_pix))
562 self.deviceInstallAction.setIconSet(QIconSet(load_pixmap('list_add', '16x16')))
563 self.deviceRemoveAction.setIconSet(QIconSet(load_pixmap('list_remove', '16x16')))
564 self.settingsConfigure.setIconSet(QIconSet(load_pixmap('settings', '16x16')))
565 self.helpContentsAction.setIconSet(QIconSet(self.help_pix))
568 self.deviceRescanAction.addTo(self.Toolbar)
569 self.deviceRefreshAll.addTo(self.Toolbar)
570 self.Toolbar.addSeparator()
571 self.deviceInstallAction.addTo(self.Toolbar)
572 self.deviceRemoveAction.addTo(self.Toolbar)
573 self.Toolbar.addSeparator()
574 self.settingsConfigure.addTo(self.Toolbar)
575 self.helpContentsAction.addTo(self.Toolbar)
580 self.InitSuppliesTab()
581 self.InitPrintSettingsTab()
582 self.InitPrintControlTab()
584 # Resize the splitter so that the device list starts as a single column
585 self.splitter2.setSizes([120, 700])
590 self.unit_names = { "year" : (self.__tr("year"), self.__tr("years")),
591 "month" : (self.__tr("month"), self.__tr("months")),
592 "week" : (self.__tr("week"), self.__tr("weeks")),
593 "day" : (self.__tr("day"), self.__tr("days")),
594 "hour" : (self.__tr("hour"), self.__tr("hours")),
595 "minute" : (self.__tr("minute"), self.__tr("minutes")),
596 "second" : (self.__tr("second"), self.__tr("seconds")),
599 self.num_repr = { 1 : self.__tr("one"),
600 2 : self.__tr("two"),
601 3 : self.__tr("three"),
602 4 : self.__tr("four"),
603 5 : self.__tr("five"),
604 6 : self.__tr("six"),
605 7 : self.__tr("seven"),
606 8 : self.__tr("eight"),
607 9 : self.__tr("nine"),
608 10 : self.__tr("ten"),
609 11 : self.__tr("eleven"),
610 12 : self.__tr("twelve")
613 if self.Latest_ver is "":
614 self.TabIndex = { self.FunctionsTab: self.UpdateFuncsTab,
615 self.StatusTab: self.UpdateStatusTab,
616 self.SuppliesTab: self.UpdateSuppliesTab,
617 self.PrintSettingsTab: self.UpdatePrintSettingsTab,
618 self.PrintJobsTab: self.UpdatePrintControlTab,
621 self.TabIndex = { self.FunctionsTab: self.UpdateFuncsTab,
622 self.StatusTab: self.UpdateStatusTab,
623 self.SuppliesTab: self.UpdateSuppliesTab,
624 self.PrintSettingsTab: self.UpdatePrintSettingsTab,
625 self.PrintJobsTab: self.UpdatePrintControlTab,
626 self.UpgradeTab:self.UpdateUpgradeTab,
631 def InitialUpdate(self):
635 if self.initial_device_uri is not None:
636 if not self.ActivateDevice(self.initial_device_uri):
637 log.error("Device %s not found" % self.initial_device_uri)
640 self.refresh_timer = QTimer(self, "RefreshTimer")
641 self.connect(self.refresh_timer, SIGNAL('timeout()'), self.TimedRefresh)
643 if MIN_AUTO_REFRESH_RATE <= self.user_settings.auto_refresh_rate <= MAX_AUTO_REFRESH_RATE:
644 self.refresh_timer.start(self.user_settings.auto_refresh_rate * 1000)
646 self.update_timer = QTimer(self)
647 self.connect(self.update_timer, SIGNAL("timeout()"), self.ThreadUpdate)
648 self.update_timer.start(500)
651 def ActivateDevice(self, device_uri):
652 log.debug(log.bold("Activate: %s %s %s" % ("*"*20, device_uri, "*"*20)))
653 d = self.DeviceList.firstItem()
657 if d.device_uri == device_uri:
659 self.DeviceList.setSelected(d, True)
660 self.DeviceList.setCurrentItem(d)
669 # ***********************************************************************************
671 # UPDATES/NOTIFICATIONS
673 # ***********************************************************************************
675 def notifier_activated(self, sock): # dbus message has arrived
678 ready = select.select([sock], [], [], 0.1)
681 m = ''.join([m, os.read(sock, self.fmt_size)])
682 if len(m) == self.fmt_size:
683 if self.cur_device is None or self.rescanning:
686 event = device.Event(*struct.unpack(self.fmt, m))
687 desc = device.queryString(event.event_code)
688 error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
689 log.debug("Status event: %s (%d)" % (event.device_uri, event.event_code))
691 if event.event_code > EVENT_MAX_USER_EVENT:
693 if event.event_code == EVENT_HISTORY_UPDATE: # 9003
694 log.debug("History update: %s" % event.device_uri)
696 if not self.rescanning:
697 dev = self.findDeviceByURI(event.device_uri)
699 self.UpdateHistory(dev)
700 self.UpdateDevice(dev)
702 elif event.event_code == EVENT_CUPS_QUEUES_CHANGED:
705 elif event.event_code == EVENT_RAISE_DEVICE_MANAGER: # 9001
706 log.debug("Raise requested")
708 self.setActiveWindow()
718 def TimedRefresh(self):
719 if not self.rescanning and self.user_settings.auto_refresh and self.allow_auto_refresh:
720 log.debug("Refresh timer...")
721 self.CleanupChildren()
723 if self.user_settings.auto_refresh_type == 0:
724 self.RequestDeviceUpdate()
729 def ThreadUpdate(self): # periodically check for updates from update thread
730 if not self.response_queue.empty():
731 response_code, device_uri = self.response_queue.get()
733 if response_code == RESPONSE_START:
734 self.statusBar().message(self.__tr("Updating %1...").arg(device_uri))
737 elif response_code == RESPONSE_DONE:
738 self.statusBar().message(QString("%1 (%2)").arg(self.cur_device_uri).\
739 arg(', '.join(self.cur_device.cups_printers)))
741 dev = self.findDeviceByURI(device_uri)
744 self.UpdateHistory(dev)
745 self.UpdateDevice(dev)
749 if self.response_queue.empty() and self.request_queue.empty():
751 # Disable thread timer until more items placed in request queue?
754 # ***********************************************************************************
756 # TAB/DEVICE CHANGE SLOTS
758 # ***********************************************************************************
760 def Tabs_currentChanged(self, tab=None):
761 """ Called when the active tab changes.
762 Update newly displayed tab.
766 tab = self.Tabs.currentPage()
770 except AttributeError:
773 def Tabs_deviceChanged(self, tab=None):
774 """ Called when the device changes.
775 Update the currently displayed tab.
778 tab = self.Tabs.currentPage()
783 # ***********************************************************************************
785 # DEVICE ICON LIST/DEVICE UPDATE(S)
787 # ***********************************************************************************
789 def DeviceList_onItem(self, a0):
793 def deviceRescanAction_activated(self):
794 self.deviceRescanAction.setEnabled(False)
795 self.RequestDeviceUpdate()
796 self.deviceRescanAction.setEnabled(True)
799 def deviceRefreshAll_activated(self):
803 def DeviceList_clicked(self,a0):
807 def CreatePixmap(self, dev=None):
809 dev = self.cur_device
813 except AttributeError:
814 dev.icon = "default_printer"
817 self.device_icons[dev.icon]
819 self.device_icons[dev.icon] = load_pixmap(dev.icon, 'devices')
821 pix = self.device_icons[dev.icon]
823 w, h = pix.width(), pix.height()
824 error_state = dev.error_state
827 p.eraseRect(0, 0, icon.width(), icon.height())
828 p.drawPixmap(0, 0, pix)
831 tech_type = dev.tech_type
832 except AttributeError:
833 tech_type = TECH_TYPE_NONE
835 if dev.device_type == DEVICE_TYPE_FAX:
836 p.drawPixmap(w - self.fax_icon.width(), 0, self.fax_icon)
838 if error_state != ERROR_STATE_CLEAR:
839 if tech_type in (TECH_TYPE_COLOR_INK, TECH_TYPE_MONO_INK):
840 status_icon = self.SMALL_ICONS[error_state][0] # ink
842 status_icon = self.SMALL_ICONS[error_state][1] # laser
844 if status_icon is not None:
845 p.drawPixmap(0, 0, status_icon)
852 def DeviceListRefresh(self):
854 log.debug("Rescanning device list...")
856 if not self.rescanning:
857 self.setCaption(self.__tr("Refreshing Device List - HP Device Manager"))
858 self.statusBar().message(self.__tr("Refreshing device list..."))
860 self.rescanning = True
861 self.cups_devices = device.getSupportedCUPSDevices(['hp', 'hpfax'])
863 devices_lock.acquire()
867 for d in self.cups_devices:
871 log.debug("Adds: %s" % ','.join(adds))
875 if d not in self.cups_devices:
878 log.debug("Removals (1): %s" % ','.join(removals))
882 if d not in adds and d not in removals:
885 log.debug("Updates: %s" % ','.join(updates))
889 log.debug("adding: %s" % d)
891 dev = device.Device(d, service=self.service, callback=self.callback,
892 disable_dbus=self.disable_dbus)
894 log.error("Unexpected error in Device class.")
897 if not dev.supported:
898 log.debug("Unsupported model - removing device.")
902 self.CheckForDeviceSettingsUI(dev)
903 icon = self.CreatePixmap(dev)
905 if dev.device_type == DEVICE_TYPE_FAX:
906 DeviceViewItem(self.DeviceList, self.__tr("%1 (Fax)").arg(dev.model_ui),
910 DeviceViewItem(self.DeviceList, self.__tr("%1 (Printer)").arg(dev.model_ui),
913 DeviceViewItem(self.DeviceList, dev.model_ui,
918 log.debug("Removals (2): %s" % ','.join(removals))
921 item = self.DeviceList.firstItem()
922 log.debug("removing: %s" % d)
930 while item is not None:
931 if item.device_uri == d:
932 self.DeviceList.takeItem(item)
935 item = item.nextItem()
939 self.DeviceList.adjustItems()
940 self.DeviceList.updateGeometry()
944 for tab in self.TabIndex:
945 self.Tabs.setTabEnabled(tab, True)
947 if self.cur_device_uri:
948 item = first_item = self.DeviceList.firstItem()
950 while item is not None:
952 if item.device_uri == self.cur_device_uri:
953 self.DeviceList.setCurrentItem(item)
954 self.DeviceList.setSelected(item, True)
955 self.statusBar().message(self.cur_device_uri)
958 item = item.nextItem()
961 self.cur_device = None
962 self.cur_device_uri = ''
964 if self.cur_device is None:
965 self.cur_device_uri = self.DeviceList.firstItem().device_uri
966 self.cur_device = devices[self.cur_device_uri]
967 self.DeviceList.setCurrentItem(self.DeviceList.firstItem())
969 self.Tabs.setTabEnabled(self.SuppliesTab, self.cur_device.device_type == DEVICE_TYPE_PRINTER and
970 self.cur_device.error_state != ERROR_STATE_ERROR)
972 self.UpdatePrinterCombos()
974 user_conf.set('last_used', 'device_uri', self.cur_device_uri)
976 for d in updates + adds:
977 if d not in removals:
978 self.RequestDeviceUpdate(devices[d])
981 self.cur_device = None
982 self.deviceRescanAction.setEnabled(False)
983 self.deviceRemoveAction.setEnabled(False)
984 self.rescanning = False
985 self.statusBar().message(self.__tr("Press F6 to refresh."))
987 for tab in self.TabIndex:
988 self.Tabs.setTabEnabled(tab, False)
990 dlg = NoDevicesForm(self, "", True)
994 self.rescanning = False
995 devices_lock.release()
997 self.deviceRescanAction.setEnabled(True)
998 self.deviceRemoveAction.setEnabled(True)
1002 def UpdateTitle(self):
1003 if self.cur_device.device_type == DEVICE_TYPE_FAX:
1004 self.setCaption(self.__tr("HP Device Manager - %1 (Fax)").arg(self.cur_device.model_ui))
1006 if self.cur_device.fax_type:
1007 self.setCaption(self.__tr("HP Device Manager - %1 (Printer)").arg(self.cur_device.model_ui))
1009 self.setCaption(self.__tr("HP Device Manager - %1").arg(self.cur_device.model_ui))
1012 def UpdateDeviceByURI(self, device_uri):
1013 return self.UpdateDevice(self.findDeviceByURI(device_uri))
1016 def UpdateDevice(self, dev=None, update_tab=True):
1017 """ Update the device icon and currently displayed tab.
1020 dev = self.cur_device
1022 log.debug("UpdateDevice(%s)" % dev.device_uri)
1024 item = self.findItem(dev)
1026 if item is not None:
1027 item.setPixmap(self.CreatePixmap(dev))
1029 if dev is self.cur_device and dev.error_state == ERROR_STATE_ERROR:
1030 self.Tabs.setCurrentPage(1)
1032 if dev is self.cur_device and update_tab:
1033 self.UpdatePrinterCombos()
1034 self.TabIndex[self.Tabs.currentPage()]()
1036 qApp.processEvents()
1039 def DeviceList_currentChanged(self, i):
1040 if i is not None: # and not self.rescanning:
1041 self.cur_device_uri = self.DeviceList.currentItem().device_uri
1042 self.cur_device = devices[self.cur_device_uri]
1043 user_conf.set('last_used', 'device_uri', self.cur_device_uri)
1045 self.Tabs.setTabEnabled(self.SuppliesTab, self.cur_device.device_type == DEVICE_TYPE_PRINTER and
1046 self.cur_device.error_state != ERROR_STATE_ERROR)
1052 def findItem(self, dev):
1054 dev = self.cur_device
1056 return self.findItemByURI(dev.device_uri)
1059 def findItemByURI(self, device_uri):
1060 item = self.DeviceList.firstItem()
1062 while item is not None:
1063 if item.device_uri == device_uri:
1065 item = item.nextItem()
1068 def findDeviceByURI(self, device_uri):
1070 return devices[device_uri]
1075 def RequestDeviceUpdate(self, dev=None, item=None):
1076 """ Submit device update request to update thread. """
1079 dev = self.cur_device
1082 #log.debug("RequestDeviceUpdate(%s)" % dev.device_uri)
1083 dev.error_state = ERROR_STATE_REFRESHING
1084 self.UpdateDevice(dev, update_tab=False)
1085 qApp.processEvents()
1087 self.request_queue.put(dev)
1090 def RescanDevices(self):
1091 #log.debug("RescanDevices()")
1092 if not self.rescanning:
1093 self.deviceRefreshAll.setEnabled(False)
1095 self.DeviceListRefresh()
1097 self.deviceRefreshAll.setEnabled(True)
1101 qApp.processEvents()
1104 # ***********************************************************************************
1106 # DEVICE LIST RIGHT CLICK
1108 # ***********************************************************************************
1110 def DeviceList_rightButtonClicked(self, item, pos):
1111 popup = QPopupMenu(self)
1113 if item is not None and item is self.DeviceList.currentItem():
1114 if self.cur_device.error_state != ERROR_STATE_ERROR:
1115 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
1116 popup.insertItem(self.__tr("Print..."), self.PrintButton_clicked)
1118 if self.cur_device.scan_type:
1119 popup.insertItem(self.__tr("Scan..."), self.ScanButton_clicked)
1121 if self.cur_device.pcard_type:
1122 popup.insertItem(self.__tr("Access Photo Cards..."), self.PCardButton_clicked)
1124 if self.cur_device.copy_type:
1125 popup.insertItem(self.__tr("Make Copies..."), self.MakeCopiesButton_clicked)
1127 elif self.cur_device.device_type == DEVICE_TYPE_FAX:
1128 if self.cur_device.fax_type:
1129 popup.insertItem(self.__tr("Send Fax..."), self.SendFaxButton_clicked)
1131 popup.insertSeparator()
1133 if self.cur_device.device_settings_ui is not None:
1134 popup.insertItem(self.__tr("Device Settings..."), self.deviceSettingsButton_clicked)
1136 if not self.rescanning:
1137 popup.insertItem(self.__tr("Refresh Device"), self.deviceRescanAction_activated)
1139 if not self.rescanning:
1140 popup.insertItem(self.__tr("Refresh All"), self.deviceRefreshAll_activated)
1145 # ***********************************************************************************
1147 # PRINTER NAME COMBOS
1149 # ***********************************************************************************
1151 def updatePrinterList(self):
1152 if self.cur_device is not None and \
1153 self.cur_device.supported:
1155 printers = cups.getPrinters()
1156 self.cur_device.cups_printers = []
1159 if p.device_uri == self.cur_device_uri:
1160 self.cur_device.cups_printers.append(p.name)
1163 def UpdatePrinterCombos(self):
1164 self.PrintSettingsPrinterCombo.clear()
1165 self.PrintJobPrinterCombo.clear()
1167 if self.cur_device is not None and \
1168 self.cur_device.supported:
1170 for c in self.cur_device.cups_printers:
1171 self.PrintSettingsPrinterCombo.insertItem(c.decode("utf-8"))
1172 self.PrintJobPrinterCombo.insertItem(c.decode("utf-8"))
1174 self.cur_printer = unicode(self.PrintSettingsPrinterCombo.currentText())
1176 def PrintSettingsPrinterCombo_activated(self, s):
1177 self.cur_printer = unicode(s)
1178 self.PrintJobPrinterCombo.setCurrentText(self.cur_printer.encode("latin1")) # TODO: ?
1179 return self.PrinterCombo_activated(self.cur_printer)
1181 def PrintJobPrinterCombo_activated(self, s):
1182 self.cur_printer = unicode(s)
1183 self.PrintSettingsPrinterCombo.setCurrentText(self.cur_printer.encode("latin1")) # TODO: ?
1184 return self.PrinterCombo_activated(self.cur_printer)
1186 def PrinterCombo_activated(self, printer):
1187 self.TabIndex[self.Tabs.currentPage()]()
1188 self.UpdatePrintSettingsTabPrinter()
1192 # ***********************************************************************************
1194 # FUNCTIONS/ACTION TAB
1196 # ***********************************************************************************
1198 def InitFuncsTab(self):
1199 self.click_lock = None
1201 def UpdateFuncsTab(self):
1202 self.iconList.clear()
1208 avail = d.device_state != DEVICE_STATE_NOT_FOUND and d.supported
1209 fax = d.fax_type and prop.fax_build and d.device_type == DEVICE_TYPE_FAX and \
1210 sys.hexversion >= 0x020300f0 and avail
1211 printer = d.device_type == DEVICE_TYPE_PRINTER and avail
1212 req_plugin = d.plugin == PLUGIN_REQUIRED
1213 opt_plugin = d.plugin == PLUGIN_OPTIONAL
1215 hplip_conf = ConfigParser.ConfigParser()
1216 fp = open("/etc/hp/hplip.conf", "r")
1217 hplip_conf.readfp(fp)
1221 plugin_installed = utils.to_bool(hplip_conf.get("hplip", "plugin"))
1222 except ConfigParser.NoOptionError:
1223 plugin_installed = False
1226 if req_plugin and plugin_installed:
1227 x = self.__tr("Download and install<br>required plugin (already installed).")
1229 elif req_plugin and not plugin_installed:
1230 x = self.__tr("Download and install<br>required plugin (needs installation).")
1232 elif opt_plugin and plugin_installed:
1233 x = self.__tr("Download and install<br>optional plugin (already installed).")
1235 elif opt_plugin and not plugin_installed:
1236 x = self.__tr("Download and install<br>optional plugin (needs installation).")
1246 (lambda : printer, # filter func
1247 self.__tr("Print"), # Text
1249 self.__tr("Print documents or files."), # Tooltip
1250 self.user_settings.cmd_print), # command/action
1252 (lambda : d.scan_type and prop.scan_build and \
1253 d.device_type == DEVICE_TYPE_PRINTER and avail,
1256 self.__tr("Scan a document, image, or photograph.<br>"),
1257 self.user_settings.cmd_scan),
1259 (lambda : d.copy_type and d.device_type == DEVICE_TYPE_PRINTER and avail,
1260 self.__tr("Make Copies"),
1262 self.__tr("Make copies on the device controlled by the PC.<br>"),
1263 self.user_settings.cmd_copy),
1265 (lambda : d.pcard_type and d.device_type == DEVICE_TYPE_PRINTER and avail,
1266 self.__tr("Unload Photo Card"),
1268 self.__tr("Copy images from the device's photo card to the PC."),
1269 self.PCardButton_clicked),
1274 self.__tr("Send Fax"),
1276 self.__tr("Send a fax from the PC."),
1277 self.user_settings.cmd_fax),
1280 self.__tr("Fax Setup"),
1282 self.__tr("Fax support must be setup before you can send faxes."),
1283 self.faxSettingsButton_clicked),
1286 self.__tr("Fax Address Book"),
1288 self.__tr("Setup fax phone numbers to use when sending faxes from the PC."),
1293 (lambda : self.cur_device.device_settings_ui is not None and avail,
1294 self.__tr("Device Settings"),
1296 self.__tr("Your device has special device settings.<br>You may alter these settings here."),
1297 self.deviceSettingsButton_clicked),
1300 self.__tr("Print Test Page"),
1302 self.__tr("Print a test page to test the setup of your printer."),
1303 self.PrintTestPageButton_clicked),
1306 self.__tr("View Printer (Queue) Information"),
1308 self.__tr("View the printers (queues) installed in CUPS."),
1309 self.viewPrinterInformation),
1312 self.__tr("View Device Information"),
1314 self.__tr("This information is primarily useful for <br>debugging and troubleshooting (advanced)."),
1315 self.viewInformation),
1317 (lambda: printer and d.align_type,
1318 self.__tr("Align Cartridges (Print Heads)"),
1320 self.__tr("This will improve the quality of output when a new cartridge is installed."),
1321 self.AlignPensButton_clicked),
1323 (lambda: printer and d.clean_type,
1324 self.__tr("Clean Cartridges"),
1326 self.__tr("You only need to perform this action if you are<br>having problems with poor printout quality due to clogged ink nozzles."),
1327 self.CleanPensButton_clicked),
1329 (lambda: printer and d.color_cal_type and d.color_cal_type == COLOR_CAL_TYPE_TYPHOON,
1330 self.__tr("Color Calibration"),
1332 self.__tr("Use this procedure to optimimize your printer's color output<br>(requires glossy photo paper)."),
1333 self.ColorCalibrationButton_clicked),
1335 (lambda: printer and d.color_cal_type and d.color_cal_type != COLOR_CAL_TYPE_TYPHOON,
1336 self.__tr("Color Calibration"),
1338 self.__tr("Use this procedure to optimimize your printer's color output."),
1339 self.ColorCalibrationButton_clicked),
1341 (lambda: printer and d.linefeed_cal_type,
1342 self.__tr("Line Feed Calibration"),
1344 self.__tr("Use line feed calibration to optimize print quality<br>(to remove gaps in the printed output)."),
1345 self.linefeedCalibration),
1347 (lambda: printer and d.pq_diag_type,
1348 self.__tr("Print Diagnostic Page"),
1350 self.__tr("Your printer can print a test page <br>to help diagnose print quality problems."),
1355 (lambda : printer and d.fw_download,
1356 self.__tr("Download Firmware"),
1358 self.__tr("Download firmware to your printer <br>(required on some devices after each power-up)."),
1359 self.ShowFirmwareDlg),
1363 (lambda : req_plugin,
1364 self.__tr("Install Required Plugin"),
1366 x, #self.__tr("Download and install the HPLIP plugin."),
1367 self.downloadPlugin),
1369 (lambda : opt_plugin,
1370 self.__tr("Install Optional Plugin"),
1372 x, #self.__tr("Download and install the HPLIP plugin."),
1373 self.downloadPlugin),
1378 self.__tr("Visit HPLIP Website"),
1380 self.__tr("Visit HPLIP website."),
1386 self.__tr("View HPLIP help."),
1390 if not self.func_icons_cached:
1391 for filter, text, icon, tooltip, cmd in self.ICONS:
1392 self.func_icons[icon] = load_pixmap(icon, '32x32')
1393 self.func_icons_cached = True
1395 for filter, text, icon, tooltip, cmd in self.ICONS:
1396 if filter is not None:
1400 FuncViewItem(self.iconList, text,
1401 self.func_icons[icon],
1406 def downloadPlugin(self):
1407 ok, sudo_ok = pkit.run_plugin_command(self.cur_device.plugin == PLUGIN_REQUIRED, self.cur_device.mq['plugin-reason'])
1409 QMessageBox.critical(self,
1411 self.__tr("<b>Unable to find an appropriate su/sudo utility to run hp-plugin.</b><p>Install kdesu, gnomesu, or gksu.</p>"),
1413 QMessageBox.NoButton,
1414 QMessageBox.NoButton)
1416 self.UpdateFuncsTab()
1419 def iconList_clicked(self, item):
1420 return self.RunFuncCmd(item)
1423 def RunFuncCmd(self, item):
1424 if item is not None and self.click_lock is not item:
1428 self.RunCommand(item.cmd)
1430 self.click_lock = item
1431 QTimer.singleShot(1000, self.UnlockClick)
1434 def UnlockClick(self):
1435 self.click_lock = None
1438 def RunFuncCmdContext(self):
1439 return self.RunFuncCmd(self.iconList.currentItem())
1442 def iconList_contextMenuRequested(self, item, pos):
1443 if item is not None and item is self.iconList.currentItem():
1444 popup = QPopupMenu(self)
1445 popup.insertItem(self.__tr("Open..."), self.RunFuncCmdContext)
1449 def iconList_returnPressed(self, item):
1450 return self.RunFuncCmd(item)
1453 def deviceSettingsButton_clicked(self):
1455 self.cur_device.open()
1456 self.cur_device.device_settings_ui(self.cur_device, self)
1458 self.cur_device.close()
1461 def setupDevice_activated(self):
1463 self.cur_device.open()
1464 self.cur_device.device_settings_ui(self.cur_device, self)
1466 self.cur_device.close()
1469 def PrintButton_clicked(self):
1470 self.RunCommand(self.user_settings.cmd_print)
1473 def ScanButton_clicked(self):
1474 self.RunCommand(self.user_settings.cmd_scan)
1477 def PCardButton_clicked(self):
1478 if self.cur_device.pcard_type == PCARD_TYPE_MLC:
1479 self.RunCommand(self.user_settings.cmd_pcard)
1481 elif self.cur_device.pcard_type == PCARD_TYPE_USB_MASS_STORAGE:
1482 self.FailureUI(self.__tr("<p><b>Photocards on your printer are only available by mounting them as drives using USB mass storage.</b><p>Please refer to your distribution's documentation for setup and usage instructions."))
1485 def SendFaxButton_clicked(self):
1486 self.RunCommand(self.user_settings.cmd_fax)
1489 def MakeCopiesButton_clicked(self):
1490 self.RunCommand(self.user_settings.cmd_copy)
1493 def ConfigureFeaturesButton_clicked(self):
1494 self.settingsConfigure_activated(2)
1497 def viewInformation(self):
1498 dlg = ScrollDialog(ScrollDeviceInfoView, self.cur_device, self.cur_printer, self.service, self)
1502 def viewPrinterInformation(self):
1503 dlg = ScrollDialog(ScrollPrinterInfoView, self.cur_device, self.cur_printer, self.service, self)
1508 f = "http://hplip.sf.net"
1511 g = os.path.join(sys_conf.get('dirs', 'doc'), 'index.html')
1512 if os.path.exists(g):
1519 def viewSupport(self):
1520 f = "http://hplip.sf.net"
1527 pq_diag = d.pq_diag_type
1530 QApplication.setOverrideCursor(QApplication.waitCursor)
1535 self.CheckDeviceUI()
1537 if d.isIdleAndNoError():
1538 QApplication.restoreOverrideCursor()
1541 maint.printQualityDiagType1(d, self.LoadPaperUI)
1544 maint.printQualityDiagType2(d, self.LoadPaperUI)
1547 self.CheckDeviceUI()
1551 QApplication.restoreOverrideCursor()
1554 def linefeedCalibration(self):
1556 linefeed_type = d.linefeed_cal_type
1559 QApplication.setOverrideCursor(QApplication.waitCursor)
1564 self.CheckDeviceUI()
1566 if d.isIdleAndNoError():
1567 QApplication.restoreOverrideCursor()
1569 if linefeed_type == 1:
1570 maint.linefeedCalType1(d, self.LoadPaperUI)
1572 elif linefeed_type == 2:
1573 maint.linefeedCalType2(d, self.LoadPaperUI)
1576 self.CheckDeviceUI()
1580 QApplication.restoreOverrideCursor()
1583 def downloadFirmware(self):
1588 QApplication.setOverrideCursor(QApplication.waitCursor)
1591 if d.isIdleAndNoError():
1592 ok = d.downloadFirmware()
1596 QApplication.restoreOverrideCursor()
1599 self.FailureUI(self.__tr("<b>An error occured downloading firmware file.</b><p>Please check your printer and ensure that the HPLIP plugin has been installed."))
1602 def CheckDeviceUI(self):
1603 self.FailureUI(self.__tr("<b>Device is busy or in an error state.</b><p>Please check device and try again."))
1606 def LoadPaperUI(self):
1607 if LoadPaperForm(self).exec_loop() == QDialog.Accepted:
1612 def AlignmentNumberUI(self, letter, hortvert, colors, line_count, choice_count):
1613 dlg = AlignForm(self, letter, hortvert, colors, line_count, choice_count)
1614 if dlg.exec_loop() == QDialog.Accepted:
1615 return True, dlg.value
1620 def PaperEdgeUI(self, maximum):
1621 dlg = PaperEdgeAlignForm(self)
1622 if dlg.exec_loop() == QDialog.Accepted:
1623 return True, dlg.value
1628 def BothPensRequiredUI(self):
1629 self.WarningUI(self.__tr("<p><b>Both cartridges are required for alignment.</b><p>Please install both cartridges and try again."))
1632 def InvalidPenUI(self):
1633 self.WarningUI(self.__tr("<p><b>One or more cartiridges are missing from the printer.</b><p>Please install cartridge(s) and try again."))
1636 def PhotoPenRequiredUI(self):
1637 self.WarningUI(self.__tr("<p><b>Both the photo and color cartridges must be inserted into the printer to perform color calibration.</b><p>If you are planning on printing with the photo cartridge, please insert it and try again."))
1640 def PhotoPenRequiredUI2(self):
1641 self.WarningUI(self.__tr("<p><b>Both the photo (regular photo or photo blue) and color cartridges must be inserted into the printer to perform color calibration.</b><p>If you are planning on printing with the photo or photo blue cartridge, please insert it and try again."))
1644 def NotPhotoOnlyRequired(self): # Type 11
1645 self.WarningUI(self.__tr("<p><b>Cannot align with only the photo cartridge installed.</b><p>Please install other cartridges and try again."))
1649 dlg = AlignType6Form1(self)
1650 return dlg.exec_loop() == QDialog.Accepted
1654 AlignType6Form2(self).exec_loop()
1657 def Align10and11UI(self, pattern, align_type):
1658 dlg = Align10Form(pattern, align_type, self)
1660 return dlg.getValues()
1663 def Align13UI(self):
1664 dlg = Align13Form(self)
1669 def AlignPensButton_clicked(self):
1671 align_type = d.align_type
1673 log.debug("Align: %s %s (type=%d) %s" % ("*"*20, self.cur_device.device_uri, align_type, "*"*20))
1676 QApplication.setOverrideCursor(QApplication.waitCursor)
1681 self.CheckDeviceUI()
1683 if d.isIdleAndNoError():
1684 QApplication.restoreOverrideCursor()
1686 if align_type == ALIGN_TYPE_AUTO:
1687 maint.AlignType1(d, self.LoadPaperUI)
1689 elif align_type == ALIGN_TYPE_8XX:
1690 maint.AlignType2(d, self.LoadPaperUI, self.AlignmentNumberUI,
1691 self.BothPensRequiredUI)
1693 elif align_type in (ALIGN_TYPE_9XX,ALIGN_TYPE_9XX_NO_EDGE_ALIGN):
1694 maint.AlignType3(d, self.LoadPaperUI, self.AlignmentNumberUI,
1695 self.PaperEdgeUI, align_type)
1697 elif align_type in (ALIGN_TYPE_LIDIL_0_3_8, ALIGN_TYPE_LIDIL_0_4_3, ALIGN_TYPE_LIDIL_VIP):
1698 maint.AlignxBow(d, align_type, self.LoadPaperUI, self.AlignmentNumberUI,
1699 self.PaperEdgeUI, self.InvalidPenUI, self.ColorAdjUI)
1701 elif align_type == ALIGN_TYPE_LIDIL_AIO:
1702 maint.AlignType6(d, self.AioUI1, self.AioUI2, self.LoadPaperUI)
1704 elif align_type == ALIGN_TYPE_DESKJET_450:
1705 maint.AlignType8(d, self.LoadPaperUI, self.AlignmentNumberUI)
1707 elif align_type == ALIGN_TYPE_LBOW:
1708 maint.AlignType10(d, self.LoadPaperUI, self.Align10and11UI)
1710 elif align_type == ALIGN_TYPE_LIDIL_0_5_4:
1711 maint.AlignType11(d, self.LoadPaperUI, self.Align10and11UI, self.NotPhotoOnlyRequired)
1713 elif align_type == ALIGN_TYPE_OJ_PRO:
1714 maint.AlignType12(d, self.LoadPaperUI)
1716 elif align_type == ALIGN_TYPE_AIO:
1717 maint.AlignType13(d, self.LoadPaperUI, self.Align13UI)
1719 elif align_type == ALIGN_TYPE_LEDM:
1720 maint.AlignType15(d, self.LoadPaperUI, self.Align13UI)
1722 elif align_type == ALIGN_TYPE_LEDM_MANUAL:
1723 maint.AlignType16(d, self.LoadPaperUI, self.AlignmentNumberUI)
1725 elif align_type == ALIGN_TYPE_LEDM_FF_CC_0:
1726 maint.AlignType17(d, self.LoadPaperUI, self.Align13UI)
1728 self.CheckDeviceUI()
1732 QApplication.restoreOverrideCursor()
1735 def ColorAdjUI(self, line, maximum=0):
1736 dlg = ColorAdjForm(self, line)
1737 if dlg.exec_loop() == QDialog.Accepted:
1738 return True, dlg.value
1743 def ColorCalUI(self):
1744 dlg = ColorCalForm(self)
1745 if dlg.exec_loop() == QDialog.Accepted:
1746 return True, dlg.value
1751 def ColorCalUI2(self):
1752 dlg = ColorCalForm2(self)
1753 if dlg.exec_loop() == QDialog.Accepted:
1754 return True, dlg.value
1759 def ColorCalUI4(self):
1760 dlg = ColorCal4Form(self)
1761 if dlg.exec_loop() == QDialog.Accepted:
1762 return True, dlg.values
1767 def ColorCalibrationButton_clicked(self):
1769 color_cal_type = d.color_cal_type
1770 log.debug("Color-cal: %s %s (type=%d) %s" % ("*"*20, self.cur_device.device_uri, color_cal_type, "*"*20))
1772 if color_cal_type == COLOR_CAL_TYPE_TYPHOON:
1773 dlg = ScrollDialog(ScrollColorCalView, self.cur_device, self.cur_printer, self.service, self)
1777 QApplication.setOverrideCursor(QApplication.waitCursor)
1782 self.CheckDeviceUI()
1784 if d.isIdleAndNoError():
1785 QApplication.restoreOverrideCursor()
1787 if color_cal_type == COLOR_CAL_TYPE_DESKJET_450:
1788 maint.colorCalType1(d, self.LoadPaperUI, self.ColorCalUI,
1789 self.PhotoPenRequiredUI)
1791 elif color_cal_type == COLOR_CAL_TYPE_MALIBU_CRICK:
1792 maint.colorCalType2(d, self.LoadPaperUI, self.ColorCalUI2,
1795 elif color_cal_type == COLOR_CAL_TYPE_STRINGRAY_LONGBOW_TORNADO:
1796 maint.colorCalType3(d, self.LoadPaperUI, self.ColorAdjUI,
1797 self.PhotoPenRequiredUI2)
1799 elif color_cal_type == COLOR_CAL_TYPE_CONNERY:
1800 maint.colorCalType4(d, self.LoadPaperUI, self.ColorCalUI4,
1803 elif color_cal_type == COLOR_CAL_TYPE_COUSTEAU:
1804 maint.colorCalType5(d, self.LoadPaperUI)
1806 elif color_cal_type == COLOR_CAL_TYPE_CARRIER:
1807 maint.colorCalType6(d, self.LoadPaperUI)
1810 self.CheckDeviceUI()
1814 QApplication.restoreOverrideCursor()
1817 def PrintTestPageButton_clicked(self):
1818 dlg = ScrollDialog(ScrollTestpageView, self.cur_device, self.cur_printer, self.service, self)
1823 return CleaningForm(self, self.cur_device, 1).exec_loop() == QDialog.Accepted
1827 return CleaningForm(self, self.cur_device, 2).exec_loop() == QDialog.Accepted
1831 CleaningForm2(self).exec_loop()
1835 def WaitUI(self, seconds):
1836 WaitForm(seconds, None, self).exec_loop()
1839 def CleanPensButton_clicked(self):
1841 clean_type = d.clean_type
1842 log.debug("Clean: %s %s (type=%d) %s" % ("*"*20, self.cur_device.device_uri, clean_type, "*"*20))
1845 QApplication.setOverrideCursor(QApplication.waitCursor)
1850 self.CheckDeviceUI()
1852 if d.isIdleAndNoError():
1853 QApplication.restoreOverrideCursor()
1855 if clean_type == CLEAN_TYPE_PCL:
1856 maint.cleaning(d, clean_type, maint.cleanType1, maint.primeType1,
1857 maint.wipeAndSpitType1, self.LoadPaperUI,
1858 self.CleanUI1, self.CleanUI2, self.CleanUI3,
1861 elif clean_type == CLEAN_TYPE_LIDIL:
1862 maint.cleaning(d, clean_type, maint.cleanType2, maint.primeType2,
1863 maint.wipeAndSpitType2, self.LoadPaperUI,
1864 self.CleanUI1, self.CleanUI2, self.CleanUI3,
1867 elif clean_type == CLEAN_TYPE_PCL_WITH_PRINTOUT:
1868 maint.cleaning(d, clean_type, maint.cleanType1, maint.primeType1,
1869 maint.wipeAndSpitType1, self.LoadPaperUI,
1870 self.CleanUI1, self.CleanUI2, self.CleanUI3,
1873 self.CheckDeviceUI()
1877 QApplication.restoreOverrideCursor()
1880 def OpenEmbeddedBrowserButton_clicked(self):
1881 utils.openURL("http://%s" % self.cur_device.host)
1884 def faxAddressBookButton_clicked(self):
1885 self.RunCommand(self.cmd_fab)
1888 def faxSettingsButton_clicked(self):
1891 self.cur_device.open()
1893 self.CheckDeviceUI()
1896 result_code, fax_num = self.cur_device.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)
1898 log.error("PML failure.")
1899 self.FailureUI(self.__tr("<p><b>Operation failed. Device busy.</b>"))
1902 fax_num = str(fax_num)
1905 result_code, name = self.cur_device.getPML(pml.OID_FAX_STATION_NAME)
1907 log.error("PML failure.")
1908 self.FailureUI(self.__tr("<p><b>Operation failed. Device busy.</b>"))
1913 dlg = FaxSettingsForm(self.cur_device, fax_num, name, self)
1917 self.cur_device.close()
1920 def addressBookButton_clicked(self):
1921 self.RunCommand(self.cmd_fab)
1924 def ShowFirmwareDlg(self):
1925 dlg = FirmwareDialog(self, self.cur_device_uri)
1927 return dlg.exec_loop() == QDialog.Accepted
1929 # ***********************************************************************************
1933 # ***********************************************************************************
1935 def InitStatusTab(self):
1936 self.statusListView.setSorting(-1)
1937 self.statusListView.setColumnText(0, QString(""))
1938 #self.statusListView.setColumnWidthMode(0, QListView.Manual)
1939 self.statusListView.setColumnWidth(0, 16)
1942 def UpdateStatusTab(self):
1943 #log.debug("UpdateStatusTab()")
1944 self.UpdateHistory()
1946 self.UpdateStatusList()
1949 def UpdatePanel(self):
1950 if self.cur_device is not None and \
1951 self.cur_device.hist and \
1952 self.cur_device.supported:
1954 dq = self.cur_device.dq
1956 if dq.get('panel', 0) == 1:
1957 line1 = dq.get('panel-line1', '')
1958 line2 = dq.get('panel-line2', '')
1961 line1 = device.queryString(self.cur_device.hist[0].event_code)
1962 except (AttributeError, TypeError):
1967 pm = load_pixmap('panel_lcd', 'other')
1971 p.setPen(QColor(0, 0, 0))
1972 p.setFont(self.font())
1974 x, y_line1, y_line2 = 10, 17, 33
1976 # TODO: Scroll long lines
1977 p.drawText(x, y_line1, line1)
1978 p.drawText(x, y_line2, line2)
1981 self.panel.setPixmap(pm)
1984 self.panel.setPixmap(load_pixmap('panel_lcd', 'other'))
1987 def UpdateHistory(self, dev=None):
1990 dev = self.cur_device
1992 return dev.queryHistory()
1994 self.cur_device.hist = [self.cur_device.last_event]
1998 def UpdateStatusList(self):
1999 self.statusListView.clear()
2001 hist = self.cur_device.hist[:]
2011 ess = device.queryString(e.event_code, 0)
2012 esl = device.queryString(e.event_code, 1)
2015 desc = self.__tr("(most recent)")
2018 desc = self.getTimeDeltaDesc(e.timedate)
2021 dt.setTime_t(int(e.timedate), Qt.LocalTime)
2023 # TODO: In Qt4.x, use QLocale.toString(date, format)
2024 tt = QString("%1 %2").arg(dt.toString()).arg(desc)
2027 job_id = unicode(e.job_id)
2031 error_state = STATUS_TO_ERROR_STATE_MAP.get(e.event_code, ERROR_STATE_CLEAR)
2032 tech_type = self.cur_device.tech_type
2035 if tech_type in (TECH_TYPE_COLOR_INK, TECH_TYPE_MONO_INK):
2036 status_pix = self.STATUS_ICONS[error_state][0] # ink
2038 status_pix = self.STATUS_ICONS[error_state][1] # laser
2040 status_pix = self.STATUS_ICONS[ERROR_STATE_CLEAR][0]
2042 StatusListViewItem(self.statusListView, status_pix, ess, tt, unicode(e.event_code),
2043 job_id, unicode(e.username))
2047 i = self.statusListView.firstChild()
2049 self.statusListView.setCurrentItem(i)
2052 def getTimeDeltaDesc(self, past):
2054 t1.setTime_t(int(past))
2055 t2 = QDateTime.currentDateTime()
2056 delta = t1.secsTo(t2)
2057 return self.__tr("(about %1 ago)").arg(self.stringify(delta))
2060 # "Nicely readable timedelta"
2061 # Credit: Bjorn Lindqvist
2062 # ASPN Python Recipe 498062
2063 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/498062
2064 # Note: Modified from recipe
2065 def seconds_in_units(self, seconds):
2066 unit_limits = [("year", 31536000),
2073 for unit_name, limit in unit_limits:
2074 if seconds >= limit:
2075 amount = int(round(float(seconds) / limit))
2076 return amount, unit_name
2078 return seconds, "second"
2081 def stringify(self, seconds):
2082 amount, unit_name = self.seconds_in_units(seconds)
2085 i18n_amount = self.num_repr[amount]
2087 i18n_amount = unicode(amount)
2090 i18n_unit = self.unit_names[unit_name][0]
2092 i18n_unit = self.unit_names[unit_name][1]
2094 return QString("%1 %2").arg(i18n_amount).arg(i18n_unit)
2099 # ***********************************************************************************
2103 # ***********************************************************************************
2105 def InitSuppliesTab(self):
2106 self.pix_battery = load_pixmap('battery', '16x16')
2109 light_yellow = "#ffffcc"
2111 light_cyan = "#ccffff"
2113 light_magenta = "#ffccff"
2116 dark_grey = "#808080"
2117 light_grey = "#c0c0c0"
2119 self.TYPE_TO_PIX_MAP = {
2120 AGENT_TYPE_UNSPECIFIED : [black],
2121 AGENT_TYPE_BLACK: [black],
2122 AGENT_TYPE_CMY: [cyan, magenta, yellow],
2123 AGENT_TYPE_KCM: [light_cyan, light_magenta, light_yellow],
2124 AGENT_TYPE_GGK: [dark_grey],
2125 AGENT_TYPE_YELLOW: [yellow],
2126 AGENT_TYPE_MAGENTA: [magenta],
2127 AGENT_TYPE_CYAN : [cyan],
2128 AGENT_TYPE_CYAN_LOW: [light_cyan],
2129 AGENT_TYPE_YELLOW_LOW: [light_yellow],
2130 AGENT_TYPE_MAGENTA_LOW: [light_magenta],
2131 AGENT_TYPE_BLUE: [blue],
2132 AGENT_TYPE_KCMY_CM: [yellow, cyan, magenta],
2133 AGENT_TYPE_LC_LM: [light_cyan, light_magenta],
2134 #AGENT_TYPE_Y_M: [yellow, magenta],
2135 #AGENT_TYPE_C_K: [black, cyan],
2136 AGENT_TYPE_LG_PK: [light_grey, dark_grey],
2137 AGENT_TYPE_LG: [light_grey],
2138 AGENT_TYPE_G: [dark_grey],
2139 AGENT_TYPE_PG: [light_grey],
2140 AGENT_TYPE_C_M: [cyan, magenta],
2141 AGENT_TYPE_K_Y: [black, yellow],
2144 self.suppliesList.setSorting(-1)
2145 self.suppliesList.setColumnText(0, QString(""))
2146 #self.suppliesList.setColumnWidthMode(0, QListView.Manual)
2147 self.suppliesList.setColumnWidth(0, 16)
2148 self.suppliesList.setColumnWidth(3, 100)
2151 def UpdateSuppliesTab(self):
2152 #log.debug("UpdateSuppliesTab()")
2154 self.suppliesList.clear()
2156 if self.cur_device is not None and \
2157 self.cur_device.supported and \
2158 self.cur_device.status_type != STATUS_TYPE_NONE and \
2159 self.cur_device.device_state != DEVICE_STATE_NOT_FOUND:
2162 self.cur_device.sorted_supplies
2163 except AttributeError:
2164 self.cur_device.sorted_supplies = []
2166 if not self.cur_device.sorted_supplies:
2170 agent_type = int(self.cur_device.dq['agent%d-type' % a])
2171 agent_kind = int(self.cur_device.dq['agent%d-kind' % a])
2172 agent_sku = self.cur_device.dq['agent%d-sku' % a]
2176 self.cur_device.sorted_supplies.append((a, agent_kind, agent_type, agent_sku))
2180 self.cur_device.sorted_supplies.sort(lambda x, y: cmp(x[1], y[1]) or cmp(x[3], y[3]), reverse=True)
2183 for x in self.cur_device.sorted_supplies:
2184 a, agent_kind, agent_type, agent_sku = x
2185 agent_level = int(self.cur_device.dq['agent%d-level' % a])
2186 agent_desc = self.cur_device.dq['agent%d-desc' % a]
2187 agent_health_desc = self.cur_device.dq['agent%d-health-desc' % a]
2191 if agent_kind in (AGENT_KIND_SUPPLY,
2193 AGENT_KIND_HEAD_AND_SUPPLY,
2194 AGENT_KIND_TONER_CARTRIDGE,
2195 AGENT_KIND_MAINT_KIT,
2197 AGENT_KIND_INT_BATTERY,
2198 AGENT_KIND_DRUM_KIT,
2201 level_pixmap = self.createBarGraph(agent_level, agent_type)
2205 if agent_kind in (AGENT_KIND_SUPPLY,
2207 AGENT_KIND_HEAD_AND_SUPPLY,
2208 AGENT_KIND_TONER_CARTRIDGE,
2209 #AGENT_KIND_MAINT_KIT,
2210 #AGENT_KIND_ADF_KIT,
2211 AGENT_KIND_INT_BATTERY,
2212 #AGENT_KIND_DRUM_KIT,
2215 pixmap = self.getIcon(agent_kind, agent_type)
2218 SuppliesListViewItem(self.suppliesList, pixmap, agent_desc,
2219 agent_sku, level_pixmap, agent_health_desc)
2221 i = self.suppliesList.firstChild()
2223 self.suppliesList.setCurrentItem(i)
2228 def getIcon(self, agent_kind, agent_type):
2229 if agent_kind in (AGENT_KIND_SUPPLY,
2231 AGENT_KIND_HEAD_AND_SUPPLY,
2232 AGENT_KIND_TONER_CARTRIDGE):
2234 map = self.TYPE_TO_PIX_MAP[agent_type]
2236 if isinstance(map, list):
2238 pix = QPixmap(16, 16) #, -1, QPixmap.DefaultOptim)
2239 pix.fill(qApp.palette().color(QPalette.Active, QColorGroup.Background))
2242 p.setBackgroundMode(Qt.OpaqueMode)
2245 p.setPen(QColor(map[0]))
2246 p.setBrush(QBrush(QColor(map[0]), Qt.SolidPattern))
2247 p.drawPie(2, 2, 10, 10, 0, 5760)
2250 p.setPen(QColor(map[0]))
2251 p.setBrush(QBrush(QColor(map[0]), Qt.SolidPattern))
2252 p.drawPie(2, 4, 8, 8, 0, 5760)
2254 p.setPen(QColor(map[1]))
2255 p.setBrush(QBrush(QColor(map[1]), Qt.SolidPattern))
2256 p.drawPie(6, 4, 8, 8, 0, 5760)
2259 p.setPen(QColor(map[2]))
2260 p.setBrush(QBrush(QColor(map[2]), Qt.SolidPattern))
2261 p.drawPie(6, 6, 8, 8, 0, 5760)
2263 p.setPen(QColor(map[1]))
2264 p.setBrush(QBrush(QColor(map[1]), Qt.SolidPattern))
2265 p.drawPie(2, 6, 8, 8, 0, 5760)
2267 p.setPen(QColor(map[0]))
2268 p.setBrush(QBrush(QColor(map[0]), Qt.SolidPattern))
2269 p.drawPie(4, 2, 8, 8, 0, 5760)
2277 elif agent_kind == AGENT_KIND_INT_BATTERY:
2278 return self.pix_battery
2281 def createBarGraph(self, percent, agent_type, w=100, h=18):
2284 px.fill(qApp.palette().color(QPalette.Active, QColorGroup.Background))
2288 pp.setBackgroundColor(qApp.palette().color(QPalette.Active, QColorGroup.Base))
2290 map = self.TYPE_TO_PIX_MAP[agent_type]
2293 if map_len == 1 or map_len > 3:
2294 pp.fillRect(0, 0, fw, h, QBrush(QColor(map[0])))
2298 pp.fillRect(0, 0, fw, h2, QBrush(QColor(map[0])))
2299 pp.fillRect(0, h2, fw, h, QBrush(QColor(map[1])))
2304 pp.fillRect(0, 0, fw, h3, QBrush(QColor(map[0])))
2305 pp.fillRect(0, h3, fw, h23, QBrush(QColor(map[1])))
2306 pp.fillRect(0, h23, fw, h, QBrush(QColor(map[2])))
2309 pp.drawRect(0, 0, w, h)
2311 if percent > 75 and agent_type in \
2312 (AGENT_TYPE_BLACK, AGENT_TYPE_UNSPECIFIED, AGENT_TYPE_BLUE):
2318 pp.drawLine(w1, 0, w1, h6)
2319 pp.drawLine(w1, h, w1, h-h6)
2321 if percent > 50 and agent_type in \
2322 (AGENT_TYPE_BLACK, AGENT_TYPE_UNSPECIFIED, AGENT_TYPE_BLUE):
2328 pp.drawLine(w2, 0, w2, h4)
2329 pp.drawLine(w2, h, w2, h-h4)
2331 if percent > 25 and agent_type in \
2332 (AGENT_TYPE_BLACK, AGENT_TYPE_UNSPECIFIED, AGENT_TYPE_BLUE):
2337 pp.drawLine(w4, 0, w4, h6)
2338 pp.drawLine(w4, h, w4, h-h6)
2344 # ***********************************************************************************
2346 # PRINTER SETTINGS TAB
2348 # ***********************************************************************************
2350 def InitPrintSettingsTab(self): # Add Scrolling Print Settings
2351 PrintJobsTabLayout = QGridLayout(self.PrintSettingsTab,1,1,11,6,"PrintJobsTabLayout")
2353 self.PrintSettingsList = ScrollPrintSettingsView(self.service, self.PrintSettingsTab, "PrintSettingsView")
2354 PrintJobsTabLayout.addMultiCellWidget(self.PrintSettingsList,1,1,0,3)
2356 self.PrintSettingsPrinterCombo = QComboBox(0,self.PrintSettingsTab,"comboBox5")
2358 self.PrintSettingsPrinterCombo.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed,0,0,
2359 self.PrintSettingsPrinterCombo.sizePolicy().hasHeightForWidth()))
2361 PrintJobsTabLayout.addWidget(self.PrintSettingsPrinterCombo, 0, 2)
2363 self.settingTextLabel = QLabel(self.PrintSettingsTab,"self.settingTextLabel")
2364 PrintJobsTabLayout.addWidget(self.settingTextLabel,0,1)
2366 self.settingTextLabel.setText(self.__tr("Printer Name:"))
2368 spacer34 = QSpacerItem(20,20,QSizePolicy.Preferred, QSizePolicy.Minimum)
2369 PrintJobsTabLayout.addItem(spacer34,0,3)
2371 spacer35 = QSpacerItem(20,20,QSizePolicy.Preferred, QSizePolicy.Minimum)
2372 PrintJobsTabLayout.addItem(spacer35,0,0)
2374 self.connect(self.PrintSettingsPrinterCombo, SIGNAL("activated(const QString&)"),
2375 self.PrintSettingsPrinterCombo_activated)
2378 def UpdatePrintSettingsTab(self):
2379 #log.debug("UpdatePrintSettingsTab()")
2380 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2381 self.settingTextLabel.setText(self.__tr("Printer Name:"))
2383 self.settingTextLabel.setText(self.__tr("Fax Name:"))
2385 self.PrintSettingsList.onDeviceChange(self.cur_device)
2388 def UpdatePrintSettingsTabPrinter(self):
2389 self.PrintSettingsList.onPrinterChange(self.cur_printer)
2392 # ***********************************************************************************
2394 # PRINTER CONTROL TAB
2396 # ***********************************************************************************
2398 def InitPrintControlTab(self):
2399 self.JOB_STATES = { cups.IPP_JOB_PENDING : self.__tr("Pending"),
2400 cups.IPP_JOB_HELD : self.__tr("On hold"),
2401 cups.IPP_JOB_PROCESSING : self.__tr("Printing"),
2402 cups.IPP_JOB_STOPPED : self.__tr("Stopped"),
2403 cups.IPP_JOB_CANCELLED : self.__tr("Canceled"),
2404 cups.IPP_JOB_ABORTED : self.__tr("Aborted"),
2405 cups.IPP_JOB_COMPLETED : self.__tr("Completed"),
2408 self.cancelToolButton.setIconSet(QIconSet(load_pixmap('cancel', '16x16')))
2409 self.infoToolButton.setIconSet(QIconSet(load_pixmap('info', '16x16')))
2411 self.JOB_STATE_ICONS = { cups.IPP_JOB_PENDING: self.busy_pix,
2412 cups.IPP_JOB_HELD : self.busy_pix,
2413 cups.IPP_JOB_PROCESSING : self.print_pix,
2414 cups.IPP_JOB_STOPPED : self.warning_pix,
2415 cups.IPP_JOB_CANCELLED : self.warning_pix,
2416 cups.IPP_JOB_ABORTED : self.error_pix,
2417 cups.IPP_JOB_COMPLETED : self.ok_pix,
2420 self.jobList.setSorting(-1)
2421 self.jobList.setColumnText(0, QString(""))
2422 #self.jobList.setColumnWidthMode(0, QListView.Manual)
2423 self.jobList.setColumnWidth(0, 16)
2424 self.jobList.setColumnText(1, QString(""))
2425 #self.jobList.setColumnWidthMode(1, QListView.Manual)
2426 self.jobList.setColumnWidth(1, 16)
2427 self.jobList.setColumnWidth(2, 300)
2428 self.cancelToolButton.setEnabled(False)
2429 self.infoToolButton.setEnabled(False)
2431 self.printer_state = cups.IPP_PRINTER_STATE_IDLE
2433 # TODO: Check queues at startup and send events if stopped or rejecting
2436 def UpdatePrintControlTab(self):
2437 #log.debug("UpdatePrintControlTab()")
2439 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2440 self.printerTextLabel.setText(self.__tr("Printer Name:"))
2443 self.printerTextLabel.setText(self.__tr("Fax Name:"))
2445 self.jobList.clear()
2446 self.UpdatePrintController()
2448 jobs = cups.getJobs()
2451 if j.dest.decode('utf-8') == unicode(self.cur_printer):
2455 if j.dest == self.cur_printer:
2456 JobListViewItem(self.jobList, self.JOB_STATE_ICONS[j.state],
2457 j.title, self.JOB_STATES[j.state], unicode(j.id))
2459 i = self.jobList.firstChild()
2461 self.jobList.setCurrentItem(i)
2464 def jobList_clicked(self, i):
2466 item = self.jobList.firstChild()
2467 while item is not None:
2471 item = item.nextSibling()
2473 self.cancelToolButton.setEnabled(num)
2474 self.infoToolButton.setEnabled(num == 1)
2477 def infoToolButton_clicked(self):
2478 item = self.jobList.firstChild()
2479 while item is not None:
2481 return self.showJobInfoDialog(item)
2483 item = item.nextSibling()
2486 def cancelToolButton_clicked(self):
2487 self.cancelCheckedJobs()
2490 def jobList_contextMenuRequested(self, item, pos, a2):
2491 if item is not None and item is self.jobList.currentItem():
2492 popup = QPopupMenu(self)
2494 popup.insertItem(self.__tr("Cancel Job"), self.cancelJob)
2495 popup.insertSeparator()
2496 popup.insertItem(self.__tr("View Job Log (advanced)..."), self.getJobInfo)
2501 def cancelJob(self):
2502 item = self.jobList.currentItem()
2504 if item is not None:
2505 self.cur_device.cancelJob(int(item.job_id))
2508 def getJobInfo(self):
2509 return self.showJobInfoDialog(self.jobList.currentItem())
2512 def showJobInfoDialog(self, item):
2513 if item is not None:
2514 text = cups.getPrintJobErrorLog(int(item.job_id))
2517 dlg = JobInfoDialog(text, self)
2518 dlg.setCaption(self.__tr("HP Device Manager - Job Log - %1 - Job %2").\
2519 arg(self.cur_printer).arg(unicode(item.job_id)))
2524 self.FailureUI(self.__tr("<b>No log output found.</b><p>If the print job is stopped or the printer is rejecting jobs, there might not be any output. Also, you will receive more output in the CUPS LogLevel is set to 'debug'."))
2527 def UpdatePrintController(self):
2529 self.defaultPushButton.setText(self.__tr("Set as Default"))
2531 default_printer = cups.getDefaultPrinter()
2532 if default_printer is not None:
2533 default_printer = default_printer.decode('utf8')
2535 if default_printer == self.cur_printer:
2536 s = self.__tr("SET AS DEFAULT")
2537 self.defaultPushButton.setEnabled(False)
2540 s = self.__tr("NOT SET AS DEFAULT")
2541 self.defaultPushButton.setEnabled(True)
2543 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2544 QToolTip.add(self.defaultPushButton, self.__tr("The printer is currently: %1").arg(s))
2547 QToolTip.add(self.defaultPushButton, self.__tr("The fax is currently: %1").arg(s))
2549 self.printer_state = cups.IPP_PRINTER_STATE_IDLE
2551 cups_printers = cups.getPrinters()
2553 for p in cups_printers:
2554 if p.name.decode('utf-8') == self.cur_printer:
2555 self.printer_state = p.state
2556 self.printer_accepting = p.accepting
2560 if self.printer_state == cups.IPP_PRINTER_STATE_IDLE:
2561 s = self.__tr("IDLE")
2563 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2564 self.stopstartPushButton.setText(self.__tr("Stop Printer"))
2567 self.stopstartPushButton.setText(self.__tr("Stop Fax"))
2569 elif self.printer_state == cups.IPP_PRINTER_STATE_PROCESSING:
2570 s = self.__tr("PROCESSING")
2572 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2573 self.stopstartPushButton.setText(self.__tr("Stop Printer"))
2576 self.stopstartPushButton.setText(self.__tr("Stop Fax"))
2578 s = self.__tr("STOPPED")
2580 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2581 self.stopstartPushButton.setText(self.__tr("Start Printer"))
2584 self.stopstartPushButton.setText(self.__tr("Start Fax"))
2586 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2587 QToolTip.add(self.stopstartPushButton, self.__tr("The printer is currently: %1").arg(s))
2590 QToolTip.add(self.stopstartPushButton, self.__tr("The fax is currently: %1").arg(s))
2593 if self.printer_accepting:
2594 s = self.__tr("ACCEPTING JOBS")
2595 self.rejectacceptPushButton.setText(self.__tr("Reject Jobs"))
2598 s = self.__tr("REJECTING JOBS")
2599 self.rejectacceptPushButton.setText(self.__tr("Accept Jobs"))
2601 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2602 QToolTip.add(self.rejectacceptPushButton, self.__tr("The printer is currently: %1").arg(s))
2605 QToolTip.add(self.rejectacceptPushButton, self.__tr("The fax is currently: %1").arg(s))
2608 def stopstartPushButton_clicked(self):
2609 QApplication.setOverrideCursor(QApplication.waitCursor)
2611 if self.printer_state in (cups.IPP_PRINTER_STATE_IDLE, cups.IPP_PRINTER_STATE_PROCESSING):
2612 result = cups.stop(self.cur_printer)
2614 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2615 e = EVENT_PRINTER_QUEUE_STOPPED
2617 e = EVENT_FAX_QUEUE_STOPPED
2620 result = cups.start(self.cur_printer)
2622 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2623 e = EVENT_PRINTER_QUEUE_STARTED
2625 e = EVENT_FAX_QUEUE_STARTED
2628 self.UpdatePrintController()
2629 self.cur_device.sendEvent(e, self.cur_printer)
2631 log.error("Start/Stop printer operation failed")
2632 self.FailureUI(self.__tr("<b>Start/Stop printer operation failed.</b><p>Try after add user to \"lp\" group."))
2635 QApplication.restoreOverrideCursor()
2638 def rejectacceptPushButton_clicked(self):
2639 QApplication.setOverrideCursor(QApplication.waitCursor)
2641 if self.printer_accepting:
2642 result = cups.reject(self.cur_printer)
2644 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2645 e = EVENT_PRINTER_QUEUE_REJECTING_JOBS
2647 e = EVENT_FAX_QUEUE_REJECTING_JOBS
2650 result = cups.accept(self.cur_printer)
2652 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2653 e = EVENT_PRINTER_QUEUE_ACCEPTING_JOBS
2655 e = EVENT_FAX_QUEUE_ACCEPTING_JOBS
2658 self.UpdatePrintController()
2659 self.cur_device.sendEvent(e, self.cur_printer)
2661 log.error("Reject/Accept jobs operation failed")
2662 self.FailureUI(self.__tr("<b>Accept/Reject printer operation failed.</b><p>Try after add user to \"lp\" group."))
2665 QApplication.restoreOverrideCursor()
2668 def defaultPushButton_clicked(self):
2669 QApplication.setOverrideCursor(QApplication.waitCursor)
2671 result = cups.setDefaultPrinter(self.cur_printer.encode('utf8'))
2673 log.error("Set default printer failed.")
2674 self.FailureUI(self.__tr("<b>Set default printer operation failed.</b><p>Try after add user to \"lp\" group."))
2676 self.UpdatePrintController()
2677 if self.cur_device.device_type == DEVICE_TYPE_PRINTER:
2678 e = EVENT_PRINTER_QUEUE_SET_AS_DEFAULT
2680 e = EVENT_FAX_QUEUE_SET_AS_DEFAULT
2682 self.cur_device.sendEvent(e, self.cur_printer)
2685 QApplication.restoreOverrideCursor()
2688 def cancelCheckedJobs(self):
2689 QApplication.setOverrideCursor(QApplication.waitCursor)
2691 item = self.jobList.firstChild()
2692 while item is not None:
2694 self.cur_device.cancelJob(int(item.job_id))
2696 item = item.nextSibling()
2699 QApplication.restoreOverrideCursor()
2701 self.UpdatePrintControlTab()
2703 def UpdateUpgradeTab(self):
2704 log.debug("Upgrade Tab is pressed")
2705 self.InstallPushButton_lock = False
2707 def InstallPushButton_clicked(self):
2708 if self.InstallPushButton_lock is True:
2711 if self.Is_autoInstaller_distro:
2712 self.InstallPushButton.setEnabled(False)
2713 terminal_cmd = utils.get_terminal()
2714 if terminal_cmd is not None and utils.which("hp-upgrade"):
2715 cmd = terminal_cmd + " 'hp-upgrade'"
2716 log.debug("cmd = %s " %cmd)
2719 log.error("Failed to run hp-upgrade command from terminal =%s "%terminal_cmd)
2720 self.InstallPushButton.setEnabled(True)
2722 self.InstallPushButton_lock = True
2723 utils.openURL("http://hplipopensource.com/hplip-web/install/manual/index.html")
2724 QTimer.singleShot(1000, self.InstallPushButton_unlock)
2726 def InstallPushButton_unlock(self):
2727 self.InstallPushButton_lock = False
2729 # ***********************************************************************************
2731 # EXIT/CHILD CLEANUP
2733 # ***********************************************************************************
2735 def closeEvent(self, event):
2737 self.request_queue.put(None)
2742 self.request_queue.put(None)
2743 self.CleanupChildren()
2744 if not self.update_thread.wait(5000):
2745 self.update_thread.terminate()
2748 def CleanupChildren(self):
2749 log.debug("Cleaning up child processes.")
2751 os.waitpid(-1, os.WNOHANG)
2756 # ***********************************************************************************
2758 # DEVICE SETTINGS PLUGIN
2760 # ***********************************************************************************
2762 def CheckForDeviceSettingsUI(self, dev):
2763 dev.device_settings_ui = None
2764 name = '.'.join(['plugins', dev.model])
2765 log.debug("Attempting to load plugin: %s" % name)
2767 mod = __import__(name, globals(), locals(), [])
2769 log.debug("No plugin found.")
2772 components = name.split('.')
2773 for c in components[1:]:
2774 mod = getattr(mod, c)
2775 log.debug("Loaded: %s" % repr(mod))
2776 dev.device_settings_ui = mod.settingsUI
2779 # ***********************************************************************************
2783 # ***********************************************************************************
2785 def settingsConfigure_activated(self, tab_to_show=0):
2786 dlg = SettingsDialog(self)
2787 dlg.TabWidget.setCurrentPage(tab_to_show)
2789 if dlg.exec_loop() == QDialog.Accepted:
2790 old_auto_refresh = self.user_settings.auto_refresh_rate
2791 self.user_settings.load()
2793 if self.user_settings.auto_refresh and old_auto_refresh != self.user_settings.auto_refresh_rate:
2794 self.refresh_timer.changeInterval(self.user_settings.auto_refresh_rate * 1000)
2796 if old_auto_refresh != self.user_settings.auto_refresh:
2797 self.autoRefresh.toggle()
2800 # ***********************************************************************************
2804 # ***********************************************************************************
2806 def deviceInstallAction_activated(self):
2807 if utils.which('hp-setup'):
2810 cmd = 'python ./setup.py --gui'
2813 utils.run(cmd, log_output=True, password_func=None, timeout=1)
2814 self.RescanDevices()
2817 def deviceRemoveAction_activated(self):
2818 if self.cur_device is not None:
2819 x = QMessageBox.critical(self,
2821 self.__tr("<b>Annoying Confirmation: Are you sure you want to remove this device?</b>"),
2823 QMessageBox.No | QMessageBox.Default,
2824 QMessageBox.NoButton)
2825 if x == QMessageBox.Yes:
2826 QApplication.setOverrideCursor(QApplication.waitCursor)
2827 print_uri = self.cur_device.device_uri
2828 fax_uri = print_uri.replace('hp:', 'hpfax:')
2830 log.debug(print_uri)
2833 self.cups_devices = device.getSupportedCUPSDevices(['hp', 'hpfax'])
2835 for d in self.cups_devices:
2836 if d in (print_uri, fax_uri):
2837 for p in self.cups_devices[d]:
2838 log.debug("Removing %s" % p)
2839 r = cups.delPrinter(p)
2841 self.FailureUI(self.__tr("<p><b>Delete printer queue fails.</b><p>Try after add user to \"lp\" group."))
2843 self.cur_device = None
2844 self.cur_device_uri = ''
2845 user_conf.set('last_used', 'device_uri', '')
2846 QApplication.restoreOverrideCursor()
2848 self.RescanDevices()
2851 # ***********************************************************************************
2855 # ***********************************************************************************
2858 def RunCommand(self, cmd, macro_char='%'):
2859 QApplication.setOverrideCursor(QApplication.waitCursor)
2863 self.FailureUI(self.__tr("<p><b>Unable to run command. No command specified.</b><p>Use <pre>Configure...</pre> to specify a command to run."))
2864 log.error("No command specified. Use settings to configure commands.")
2866 log.debug("Run: %s %s (%s) %s" % ("*"*20, cmd, self.cur_device_uri, "*"*20))
2870 cmd = ''.join([self.cur_device.device_vars.get(x, x) \
2871 for x in cmd.split(macro_char)])
2872 except AttributeError:
2877 path = cmd.split()[0]
2883 self.CleanupChildren()
2884 os.spawnvp(os.P_NOWAIT, path, args)
2885 qApp.processEvents()
2888 QApplication.restoreOverrideCursor()
2891 def helpContents(self):
2892 f = "http://hplip.sf.net"
2895 g = os.path.join(sys_conf.get('dirs', 'doc'), 'index.html')
2896 if os.path.exists(g):
2903 def helpAbout(self):
2904 dlg = AboutDlg(self)
2905 dlg.VersionText.setText(prop.version)
2906 dlg.ToolboxVersionText.setText(self.toolbox_version + " (Qt3)")
2910 def FailureUI(self, error_text):
2911 QMessageBox.critical(self,
2915 QMessageBox.NoButton,
2916 QMessageBox.NoButton)
2919 def WarningUI(self, msg):
2920 QMessageBox.warning(self,
2924 QMessageBox.NoButton,
2925 QMessageBox.NoButton)
2928 def __tr(self,s,c = None):
2929 return qApp.translate("DevMgr4",s,c)
2933 # ***********************************************************************************
2935 # ScrollDeviceInfoView (View Device Information)
2937 # ***********************************************************************************
2939 class ScrollDeviceInfoView(ScrollView):
2940 def __init__(self, service, parent=None, form=None, name=None, fl=0):
2941 ScrollView.__init__(self, service, parent, name, fl)
2944 def fillControls(self):
2945 ScrollView.fillControls(self)
2946 self.addDeviceInfo()
2947 self.maximizeControl()
2950 def addDeviceInfo(self):
2951 self.addGroupHeading("info_title", self.__tr("Device Information"))
2953 widget = self.getWidget()
2955 layout37 = QGridLayout(widget,1,1,5,10,"layout37")
2957 self.infoListView = QListView(widget,"fileListView")
2958 self.infoListView.addColumn(self.__tr("Static/Dynamic"))
2959 self.infoListView.addColumn(self.__tr("Key"))
2960 self.infoListView.addColumn(self.__tr("Value"))
2961 self.infoListView.setAllColumnsShowFocus(1)
2962 self.infoListView.setShowSortIndicator(1)
2963 self.infoListView.setColumnWidth(0, 50)
2964 self.infoListView.setColumnWidth(1, 150)
2965 self.infoListView.setColumnWidth(2, 300)
2966 self.infoListView.setItemMargin(2)
2967 self.infoListView.setSorting(-1)
2969 layout37.addMultiCellWidget(self.infoListView,1,1,0,3)
2971 mq_keys = self.cur_device.mq.keys()
2974 for key,i in zip(mq_keys, range(len(mq_keys))):
2975 QListViewItem(self.infoListView, self.__tr("Static"), key, str(self.cur_device.mq[key]))
2977 dq_keys = self.cur_device.dq.keys()
2980 for key,i in zip(dq_keys, range(len(dq_keys))):
2981 QListViewItem(self.infoListView, self.__tr("Dynamic"), key, str(self.cur_device.dq[key]))
2983 self.addWidget(widget, "file_list", maximize=True)
2986 def __tr(self,s,c = None):
2987 return qApp.translate("ScrollDeviceInfoView",s,c)
2991 # ***********************************************************************************
2993 # ScrollTestpageView (Print Test Page)
2995 # ***********************************************************************************
2997 class ScrollTestpageView(ScrollView):
2998 def __init__(self, service, parent=None, form=None, name=None, fl=0):
2999 ScrollView.__init__(self, service, parent, name, fl)
3000 self.dialog = parent
3003 def fillControls(self):
3004 ScrollView.fillControls(self)
3006 if self.addPrinterFaxList():
3007 self.addTestpageType()
3011 self.printButton = self.addActionButton("bottom_nav", self.__tr("Print Test Page"),
3012 self.printButton_clicked, 'print.png', None)
3015 def addTestpageType(self):
3016 self.addGroupHeading("testpage_type", self.__tr("Test Page Type"))
3017 widget = self.getWidget()
3019 Form4Layout = QGridLayout(widget,1,1,5,10,"Form4Layout")
3021 self.buttonGroup3 = QButtonGroup(widget,"buttonGroup3")
3022 self.buttonGroup3.setLineWidth(0)
3023 self.buttonGroup3.setColumnLayout(0,Qt.Vertical)
3024 self.buttonGroup3.layout().setSpacing(5)
3025 self.buttonGroup3.layout().setMargin(10)
3027 buttonGroup3Layout = QGridLayout(self.buttonGroup3.layout())
3028 buttonGroup3Layout.setAlignment(Qt.AlignTop)
3030 self.radioButton6 = QRadioButton(self.buttonGroup3,"radioButton6")
3031 self.radioButton6.setEnabled(False)
3032 buttonGroup3Layout.addWidget(self.radioButton6,1,0)
3034 self.radioButton5 = QRadioButton(self.buttonGroup3,"radioButton5")
3035 self.radioButton5.setChecked(1)
3036 buttonGroup3Layout.addWidget(self.radioButton5,0,0)
3038 Form4Layout.addWidget(self.buttonGroup3,0,0)
3040 self.radioButton6.setText(self.__tr("Printer diagnostic page (does not test print driver)"))
3041 self.radioButton5.setText(self.__tr("HPLIP test page (tests print driver)"))
3043 self.addWidget(widget, "page_type")
3046 def printButton_clicked(self):
3048 printer_name = self.cur_printer
3052 QApplication.setOverrideCursor(QApplication.waitCursor)
3057 self.CheckDeviceUI()
3060 if d.isIdleAndNoError():
3061 QApplication.restoreOverrideCursor()
3064 d.printTestPage(printer_name)
3069 self.CheckDeviceUI()
3071 self.CheckDeviceUI()
3074 QApplication.restoreOverrideCursor()
3077 QMessageBox.information(self,
3079 self.__tr("<p><b>A test page should be printing on your printer.</b><p>If the page fails to print, please visit http://hplip.sourceforge.net for troubleshooting and support."),
3081 QMessageBox.NoButton,
3082 QMessageBox.NoButton)
3084 self.dialog.accept()
3087 def CheckDeviceUI(self):
3088 self.FailureUI(self.__tr("<b>Device is busy or in an error state.</b><p>Please check device and try again."))
3091 def FailureUI(self, error_text):
3092 QMessageBox.critical(self,
3096 QMessageBox.NoButton,
3097 QMessageBox.NoButton)
3100 def __tr(self,s,c = None):
3101 return qApp.translate("ScrollTestpageView",s,c)
3103 # ***********************************************************************************
3105 # ScrollPrinterInfoView (View Device Information)
3107 # ***********************************************************************************
3109 class ScrollPrinterInfoView(ScrollView):
3110 def __init__(self, service, parent = None, form=None, name = None,fl = 0):
3111 ScrollView.__init__(self, service, parent, name, fl)
3114 def fillControls(self):
3115 ScrollView.fillControls(self)
3118 for p in self.printers:
3119 if p.device_uri == self.cur_device.device_uri:
3123 self.addGroupHeading("error_title", self.__tr("No printers found for this device."))
3126 self.addPrinterInfo(p)
3128 self.maximizeControl()
3131 def addPrinterInfo(self, p):
3132 self.addGroupHeading(p.name, p.name)
3133 widget = self.getWidget()
3135 layout1 = QVBoxLayout(widget,5,10,"layout1")
3137 textLabel2 = QLabel(widget,"textLabel2")
3139 if p.device_uri.startswith("hpfax:"):
3140 s = self.__tr("Fax")
3142 s = self.__tr("Printer")
3144 textLabel2.setText(self.__tr("Type: %1").arg(s))
3145 layout1.addWidget(textLabel2)
3147 textLabel3 = QLabel(widget,"textLabel3")
3148 textLabel3.setText(self.__tr("Location: %1").arg(p.location))
3149 layout1.addWidget(textLabel3)
3151 textLabel4 = QLabel(widget,"textLabel4")
3152 textLabel4.setText(self.__tr("Description/Info: %1").arg(p.info))
3153 layout1.addWidget(textLabel4)
3155 textLabel5 = QLabel(widget,"textLabel5")
3157 if p.state == cups.IPP_PRINTER_STATE_IDLE:
3158 s = self.__tr("Idle")
3159 elif p.state == cups.IPP_PRINTER_STATE_PROCESSING:
3160 s = self.__tr("Processing")
3161 elif p.state == cups.IPP_PRINTER_STATE_STOPPED:
3162 s = self.__tr("Stopped")
3164 s = self.__tr("Unknown")
3166 textLabel5.setText(self.__tr("State: %1").arg(s))
3167 layout1.addWidget(textLabel5)
3169 textLabel6 = QLabel(widget,"textLabel6")
3170 textLabel6.setText(self.__tr("PPD/Driver: %1").arg(p.makemodel))
3171 layout1.addWidget(textLabel6)
3173 textLabel7 = QLabel(widget,"textLabel7")
3174 textLabel7.setText(self.__tr("CUPS/IPP Printer URI: %1").arg(p.printer_uri))
3175 layout1.addWidget(textLabel7)
3177 self.addWidget(widget, p.name)
3180 def __tr(self,s,c = None):
3181 return qApp.translate("ScrollPrinterInfoView",s,c)
3186 # ***********************************************************************************
3190 # ***********************************************************************************
3192 class ScrollColorCalView(ScrollView):
3193 def __init__(self, service, parent = None, form=None, name = None,fl = 0):
3194 ScrollView.__init__(self, service, parent, name, fl)
3195 self.dialog = parent
3198 def fillControls(self):
3199 ScrollView.fillControls(self)
3200 self.addLoadPaper(PAPER_TYPE_HP_ADV_PHOTO)
3202 self.printButton = self.addActionButton("bottom_nav", self.__tr("Perform Color Calibration"),
3203 self.colorcalButton_clicked, 'print.png', None)
3206 def colorcalButton_clicked(self):
3208 printer_name = self.cur_printer
3212 QApplication.setOverrideCursor(QApplication.waitCursor)
3217 self.CheckDeviceUI()
3219 if d.isIdleAndNoError():
3220 QApplication.restoreOverrideCursor()
3223 d.setPML(pml.OID_PRINT_INTERNAL_PAGE, pml.PRINT_INTERNAL_PAGE_AUTOMATIC_COLOR_CALIBRATION)
3228 self.CheckDeviceUI()
3231 QApplication.restoreOverrideCursor()
3234 QMessageBox.information(self,
3236 self.__tr("<p><b>A test page should be printing on your printer.</b><p>If the page fails to print, please visit http://hplip.sourceforge.net for troubleshooting and support."),
3238 QMessageBox.NoButton,
3239 QMessageBox.NoButton)
3241 self.dialog.accept()
3244 def CheckDeviceUI(self):
3245 self.FailureUI(self.__tr("<b>Device is busy or in an error state.</b><p>Please check device and try again."))
3248 def FailureUI(self, error_text):
3249 QMessageBox.critical(self,
3253 QMessageBox.NoButton,
3254 QMessageBox.NoButton)
3257 def __tr(self,s,c = None):
3258 return qApp.translate("ScrollColorCalView",s,c)