2 # -*- coding: utf-8 -*-
4 # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 from base import device, utils, models
35 from base.codes import *
36 from ui_utils import *
40 from PyQt4.QtCore import *
41 from PyQt4.QtGui import *
43 log.error("Python bindings for Qt4 not found. Try using --qt3. Exiting!")
46 from systrayframe import SystrayFrame
52 from dbus import SessionBus, lowlevel
53 #from dbus.mainloop.qt import DBusQtMainLoop
55 log.error("Python bindings for dbus not found. Exiting!")
59 # Ignore: .../dbus/connection.py:242: DeprecationWarning: object.__init__() takes no parameters
60 # (occurring on Python 2.6/dBus 0.83/Ubuntu 9.04)
61 warnings.simplefilter("ignore", DeprecationWarning)
72 TRAY_MESSAGE_DELAY = 10000
73 HIDE_INACTIVE_DELAY = 5000
77 UPGRADE_CHECK_DELAY=24*60*60*1000 #1 day
79 ERROR_STATE_TO_ICON = {
80 ERROR_STATE_CLEAR: QSystemTrayIcon.Information,
81 ERROR_STATE_OK: QSystemTrayIcon.Information,
82 ERROR_STATE_WARNING: QSystemTrayIcon.Warning,
83 ERROR_STATE_ERROR: QSystemTrayIcon.Critical,
84 ERROR_STATE_LOW_SUPPLIES: QSystemTrayIcon.Warning,
85 ERROR_STATE_BUSY: QSystemTrayIcon.Warning,
86 ERROR_STATE_LOW_PAPER: QSystemTrayIcon.Warning,
87 ERROR_STATE_PRINTING: QSystemTrayIcon.Information,
88 ERROR_STATE_SCANNING: QSystemTrayIcon.Information,
89 ERROR_STATE_PHOTOCARD: QSystemTrayIcon.Information,
90 ERROR_STATE_FAXING: QSystemTrayIcon.Information,
91 ERROR_STATE_COPYING: QSystemTrayIcon.Information,
95 info = getPynotifyIcon('info')
96 warn = getPynotifyIcon('warning')
97 err = getPynotifyIcon('error')
98 ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY = {
99 ERROR_STATE_CLEAR: (info, pynotify.URGENCY_LOW),
100 ERROR_STATE_OK: (info, pynotify.URGENCY_LOW),
101 ERROR_STATE_WARNING: (warn, pynotify.URGENCY_NORMAL),
102 ERROR_STATE_ERROR: (err, pynotify.URGENCY_CRITICAL),
103 ERROR_STATE_LOW_SUPPLIES: (warn, pynotify.URGENCY_NORMAL),
104 ERROR_STATE_BUSY: (warn, pynotify.URGENCY_NORMAL),
105 ERROR_STATE_LOW_PAPER: (warn, pynotify.URGENCY_NORMAL),
106 ERROR_STATE_PRINTING: (info, pynotify.URGENCY_LOW),
107 ERROR_STATE_SCANNING: (info, pynotify.URGENCY_LOW),
108 ERROR_STATE_PHOTOCARD: (info, pynotify.URGENCY_LOW),
109 ERROR_STATE_FAXING: (info, pynotify.URGENCY_LOW),
110 ERROR_STATE_COPYING: (info, pynotify.URGENCY_LOW),
113 devices = {} # { <device_uri> : HistoryDevice(), ... }
116 class DeviceMenu(QMenu):
117 def __init__(self, title, parent, device_uri, device_hist, index):
118 QMenu.__init__(self, title, parent)
119 self.device_uri = device_uri
120 self.device_hist = device_hist
129 for e in self.device_hist:
130 error_state = STATUS_TO_ERROR_STATE_MAP.get(e.event_code, ERROR_STATE_CLEAR)
131 ess = device.queryString(e.event_code, 0)
133 a = QAction(QIcon(getStatusListIcon(error_state)[self.index]),
134 QString("%1 %2").arg(ess).arg(getTimeDeltaDesc(e.timedate)), self)
140 self.setIcon(QIcon(getStatusListIcon(error_state)[self.index]))
146 self.addAction(QIcon(load_pixmap("warning", "16x16")),
147 QApplication.translate("SystemTray", "(No events)", None, QApplication.UnicodeUTF8))
151 class HistoryDevice(QObject):
152 def __init__(self, device_uri, needs_update=True):
153 self.needs_update = needs_update
154 self.device_uri = device_uri
156 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
157 device.parseDeviceURI(device_uri)
168 self.model = models.normalizeModelUIName(model)
171 self.device_type = DEVICE_TYPE_PRINTER
172 self.menu_text = self.__tr("%1 Printer (%2)").arg(self.model).arg(self.id)
174 elif back_end == 'hpaio':
175 self.device_type = DEVICE_TYPE_SCANNER
176 self.menu_text = self.__tr("%1 Scanner (%2)").arg(self.model).arg(self.id)
178 elif back_end == 'hpfax':
179 self.device_type = DEVICE_TYPE_FAX
180 self.menu_text = self.__tr("%1 Fax (%2)").arg(self.model).arg(self.id)
183 self.device_type = DEVICE_TYPE_UNKNOWN
184 self.menu_text = self.__tr("%1 (%2)").arg(self.model).arg(self.id)
186 self.mq = device.queryModelByURI(self.device_uri)
188 if self.mq.get('tech-type', TECH_TYPE_NONE) in (TECH_TYPE_MONO_LASER, TECH_TYPE_COLOR_LASER):
193 def getHistory(self, service):
194 if service is not None and self.needs_update:
195 device_uri, h = service.GetHistory(self.device_uri)
196 self.history = [device.Event(*tuple(e)) for e in list(h)[:-MAX_MENU_EVENTS:-1]]
197 self.needs_update = False
200 def __tr(self, s, c=None):
201 return QApplication.translate("SystemTray", s, c, QApplication.UnicodeUTF8)
206 class SystraySettingsDialog(QDialog):
207 def __init__(self, parent, systray_visible, polling,
208 polling_interval, systray_messages,
211 upgrade_pending_time=0,
212 upgrade_last_update_time=0,
215 # upgrade_pending_update_time=0,
218 QDialog.__init__(self, parent)
220 self.systray_visible = systray_visible
221 self.systray_messages = systray_messages
223 if device_list is not None:
224 self.device_list = device_list
226 self.device_list = {}
228 self.polling = polling
229 self.polling_interval = polling_interval
230 self.upgrade_notify =upgrade_notify
231 self.upgrade_last_update_time=upgrade_last_update_time
232 self.upgrade_pending_time=upgrade_pending_time
233 self.upgrade_msg=upgrade_msg
236 self.SystemTraySettings.updateUi()
240 self.setObjectName("SystraySettingsDialog")
241 self.resize(QSize(QRect(0,0,488,565).size()).expandedTo(self.minimumSizeHint()))
243 self.gridlayout = QGridLayout(self)
244 self.gridlayout.setObjectName("gridlayout")
246 self.SystemTraySettings = SystrayFrame(self)
247 self.SystemTraySettings.initUi(self.systray_visible,
248 self.polling, self.polling_interval,
250 self.systray_messages,
252 self.upgrade_pending_time,
255 sizePolicy = QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
256 sizePolicy.setHorizontalStretch(0)
257 sizePolicy.setVerticalStretch(0)
258 sizePolicy.setHeightForWidth(self.SystemTraySettings.sizePolicy().hasHeightForWidth())
259 self.SystemTraySettings.setSizePolicy(sizePolicy)
260 self.SystemTraySettings.setFrameShadow(QFrame.Raised)
261 self.SystemTraySettings.setObjectName("SystemTraySettings")
262 self.gridlayout.addWidget(self.SystemTraySettings,0,0,1,2)
264 spacerItem = QSpacerItem(301,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
265 self.gridlayout.addItem(spacerItem,1,0,1,1)
267 self.StdButtons = QDialogButtonBox(self)
268 self.StdButtons.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.NoButton|QDialogButtonBox.Ok)
269 self.StdButtons.setCenterButtons(False)
270 self.StdButtons.setObjectName("StdButtons")
271 self.gridlayout.addWidget(self.StdButtons,1,1,1,1)
273 QObject.connect(self.StdButtons, SIGNAL("accepted()"), self.acceptClicked)
274 QObject.connect(self.StdButtons, SIGNAL("rejected()"), self.reject)
275 #QMetaObject.connectSlotsByName(self)
277 self.setWindowTitle(self.__tr("HP Device Manager - System Tray Settings"))
278 self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128')))
279 # pm = load_pixmap("hp_logo", "32x32")
280 # self.prop_icon = QIcon(pm)
283 def acceptClicked(self):
284 self.systray_visible = self.SystemTraySettings.systray_visible
285 self.polling = self.SystemTraySettings.polling
286 self.polling_interval = self.SystemTraySettings.polling_interval
287 self.device_list = self.SystemTraySettings.device_list
288 self.systray_messages = self.SystemTraySettings.systray_messages
289 self.upgrade_notify =self.SystemTraySettings.upgrade_notify
293 def __tr(self, s, c=None):
294 return QApplication.translate("SystraySettingsDialog", s, c, QApplication.UnicodeUTF8)
299 class SystemTrayApp(QApplication):
300 def __init__(self, args, read_pipe):
301 QApplication.__init__(self, args)
304 self.read_pipe = read_pipe
305 self.fmt = "80s80sI32sI80sf"
306 self.fmt_size = struct.calcsize(self.fmt)
307 self.timer_active = False
308 self.active_icon = False
309 self.user_settings = UserSettings()
310 self.user_settings.load()
311 self.user_settings.debug()
313 self.tray_icon = QSystemTrayIcon()
315 pm = load_pixmap("hp_logo", "32x32")
316 self.prop_icon = QIcon(pm)
318 a = load_pixmap('active', '16x16')
319 painter = QPainter(pm)
320 painter.drawPixmap(32, 0, a)
323 self.prop_active_icon = QIcon(pm)
325 self.tray_icon.setIcon(self.prop_icon)
327 self.session_bus = SessionBus()
330 for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
333 self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
334 QObject.connect(self.tray_icon, SIGNAL("messageClicked()"), self.messageClicked)
335 notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
336 QObject.connect(notifier, SIGNAL("activated(int)"), self.notifierActivated)
337 QObject.connect(self.tray_icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.trayActivated)
338 self.tray_icon.show()
340 if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
341 self.tray_icon.setVisible(True)
343 QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive) # show icon for awhile @ startup
345 self.tray_icon.setIcon(self.prop_active_icon)
346 self.active_icon = True
348 self.handle_hplip_updation()
349 QTimer.singleShot(SET_MENU_DELAY, self.initDone)
351 self.timer = QTimer()
352 self.timer.connect(self.timer,SIGNAL("timeout()"),self.handle_hplip_updation)
353 self.timer.start(UPGRADE_CHECK_DELAY)
358 self.tray_icon.setIcon(self.prop_icon)
359 self.active_icon = False
364 def addDevice(self, device_uri):
368 devices[device_uri] = HistoryDevice(device_uri)
370 devices[device_uri].needs_update = True
373 def handle_hplip_updation(self):
374 log.debug("handle_hplip_updation upgrade_notify =%d"%(self.user_settings.upgrade_notify))
375 path = utils.which('hp-upgrade')
376 if self.user_settings.upgrade_notify is False:
377 log.debug("upgrade notification is disabled in systray ")
379 path = os.path.join(path, 'hp-upgrade')
380 log.debug("Running hp-upgrade: %s " % (path))
381 # this just updates the available version in conf file. But won't notify
382 os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--check')
386 current_time = time.time()
388 if int(current_time) > self.user_settings.upgrade_pending_update_time:
389 path = utils.which('hp-upgrade')
391 path = os.path.join(path, 'hp-upgrade')
392 log.debug("Running hp-upgrade: %s " % (path))
393 os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--notify')
396 log.error("Unable to find hp-upgrade --notify on PATH.")
398 log.debug("upgrade schedule time is not yet completed. schedule time =%d current time =%d " %(self.user_settings.upgrade_pending_update_time, current_time))
408 title = QWidgetAction(self.menu)
409 #title.setDisabled(True)
411 hbox = QFrame(self.menu)
412 layout = QHBoxLayout(hbox)
415 pix_label = QLabel(hbox)
417 layout.insertWidget(-1, pix_label, 0)
419 icon_size = self.menu.style().pixelMetric(QStyle.PM_SmallIconSize)
420 pix_label.setPixmap(self.prop_icon.pixmap(icon_size))
423 layout.insertWidget(-1, label, 20)
424 title.setDefaultWidget(hbox)
426 label.setText(self.__tr("HPLIP Status Service"))
431 self.menu.insertAction(None, title)
434 if self.service is None:
438 self.service = self.session_bus.get_object('com.hplip.StatusService',
439 "/com/hplip/StatusService")
440 except DBusException:
441 log.warn("Unable to connect to StatusService. Retrying...")
446 if self.service is not None:
447 self.menu.addSeparator()
450 devices[d].getHistory(self.service)
452 menu = DeviceMenu(devices[d].menu_text, self.menu, d, devices[d].history, devices[d].index)
453 self.menu.addMenu(menu)
457 self.menu.addSeparator()
458 self.menu.addAction(self.__tr("HP Device Manager..."), self.toolboxTriggered)
460 self.menu.addSeparator()
462 self.settings_action = self.menu.addAction(QIcon(load_pixmap('settings', '16x16')),
463 self.__tr("Settings..."), self.settingsTriggered)
465 self.menu.addSeparator()
466 self.menu.addAction(QIcon(load_pixmap('quit', '16x16')), "Quit", self.quitTriggered)
467 self.tray_icon.setContextMenu(self.menu)
472 def settingsTriggered(self):
473 if self.menu is None:
476 self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING)
478 cur_vers = sys_conf.get('hplip', 'version')
479 self.user_settings.load()
480 installed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_last_update_time))
481 if utils.Is_HPLIP_older_version(cur_vers, self.user_settings.latest_available_version):
482 if int(time.time()) < self.user_settings.upgrade_pending_update_time :
483 postponed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_pending_update_time))
484 upgrade_msg ="HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade. HPLIP upgrade is scheduled on %s." %(cur_vers,installed_time , self.user_settings.latest_available_version, postponed_time)
485 elif self.user_settings.upgrade_last_update_time:
486 upgrade_msg ="HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade." %(cur_vers,installed_time , self.user_settings.latest_available_version)
488 upgrade_msg ="HPLIP-%s version was installed.\n\nNew version of HPLIP-%s is available for upgrade." %(cur_vers, self.user_settings.latest_available_version)
489 elif self.user_settings.upgrade_last_update_time:
490 upgrade_msg ="HPLIP-%s version was installed on %s."%(cur_vers, installed_time)
492 upgrade_msg ="HPLIP-%s version was installed."%(cur_vers)
496 dlg = SystraySettingsDialog(self.menu, self.user_settings.systray_visible,
497 self.user_settings.polling, self.user_settings.polling_interval,
498 self.user_settings.systray_messages,
499 self.user_settings.polling_device_list,
500 self.user_settings.upgrade_notify,
501 self.user_settings.upgrade_pending_update_time,
502 self.user_settings.upgrade_last_update_time,
506 if dlg.exec_() == QDialog.Accepted:
507 self.user_settings.systray_visible = dlg.systray_visible
508 self.user_settings.systray_messages = dlg.systray_messages
509 self.user_settings.upgrade_notify = dlg.upgrade_notify
511 log.debug("HPLIP update notification = %d"%(self.user_settings.upgrade_notify))
512 self.user_settings.save()
514 if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
515 log.debug("Showing...")
516 self.tray_icon.setVisible(True)
519 log.debug("Waiting to hide...")
520 QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)
522 self.sendMessage('', '', EVENT_USER_CONFIGURATION_CHANGED)
525 self.sendMessage('', '', EVENT_DEVICE_START_POLLING)
528 def timeoutHideWhenInactive(self):
529 log.debug("Hiding...")
530 if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
531 self.tray_icon.setVisible(False)
535 def updateMenu(self):
536 if self.menu is None:
538 for a in self.menu.actions():
541 except AttributeError:
546 def trayActivated(self, reason):
547 if reason == QSystemTrayIcon.Context:
551 elif reason == QSystemTrayIcon.DoubleClick:
552 #print "double click"
553 self.toolboxTriggered()
556 elif reason == QSystemTrayIcon.Trigger:
557 #print "single click"
560 elif reason == QSystemTrayIcon.MiddleClick:
561 #print "middle click"
565 def messageClicked(self):
566 #print "\nPARENT: message clicked"
570 def quitTriggered(self):
572 self.sendMessage('', '', EVENT_SYSTEMTRAY_EXIT)
576 def toolboxTriggered(self):
578 os.waitpid(-1, os.WNOHANG)
582 # See if it is already running...
583 ok, lock_file = utils.lock_app('hp-toolbox', True)
585 if ok: # able to lock, not running...
586 utils.unlock(lock_file)
588 path = utils.which('hp-toolbox')
590 path = os.path.join(path, 'hp-toolbox')
592 self.tray_icon.showMessage(self.__tr("HPLIP Status Service"),
593 self.__tr("Unable to locate hp-toolbox on system PATH."),
594 QSystemTrayIcon.Critical, TRAY_MESSAGE_DELAY)
596 log.error("Unable to find hp-toolbox on PATH.")
600 log.debug("Running hp-toolbox: hp-toolbox")
601 os.spawnlp(os.P_NOWAIT, path, 'hp-toolbox')
603 else: # ...already running, raise it
604 self.sendMessage('', '', EVENT_RAISE_DEVICE_MANAGER, interface='com.hplip.Toolbox')
607 def sendMessage(self, device_uri, printer_name, event_code, username=prop.username,
608 job_id=0, title='', pipe_name='', interface='com.hplip.StatusService'):
609 #device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(SessionBus(), interface)
610 device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(self.session_bus, interface)
613 def notifierActivated(self, s):
617 r, w, e = select.select([self.read_pipe], [], [self.read_pipe], 1.0)
619 log.debug("Error in select()")
623 log.error("Pipe error: %s" % e)
627 m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
628 while len(m) >= self.fmt_size:
629 event = device.Event(*struct.unpack(self.fmt, m[:self.fmt_size]))
631 m = m[self.fmt_size:]
633 if event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
634 log.debug("Re-reading configuration (EVENT_USER_CONFIGURATION_CHANGED)")
635 self.user_settings.load()
636 self.user_settings.debug()
638 elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
642 if self.user_settings.systray_visible in \
643 (SYSTRAY_VISIBLE_SHOW_ALWAYS, SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE):
645 log.debug("Showing...")
646 self.tray_icon.setVisible(True)
648 if event.event_code == EVENT_DEVICE_UPDATE_ACTIVE:
649 if not self.active_icon:
650 self.tray_icon.setIcon(self.prop_active_icon)
651 self.active_icon = True
654 elif event.event_code == EVENT_DEVICE_UPDATE_INACTIVE:
656 self.tray_icon.setIcon(self.prop_icon)
657 self.active_icon = False
660 elif event.event_code == EVENT_DEVICE_UPDATE_BLIP:
661 if not self.active_icon:
662 self.tray_icon.setIcon(self.prop_active_icon)
663 self.active_icon = True
664 QTimer.singleShot(BLIP_DELAY, self.blipTimeout)
667 if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
668 log.debug("Waiting to hide...")
669 QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)
671 if event.event_code <= EVENT_MAX_USER_EVENT:
672 self.addDevice(event.device_uri)
675 if self.tray_icon.supportsMessages():
677 log.debug("Tray icon message:")
680 error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
681 desc = device.queryString(event.event_code)
684 if self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ALL: # OK, Busy
687 elif self.user_settings.systray_messages in (SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS, SYSTRAY_MESSAGES_SHOW_ERRORS_ONLY):
688 if error_state == ERROR_STATE_ERROR:
691 elif self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS and \
692 error_state in (ERROR_STATE_WARNING, ERROR_STATE_LOW_SUPPLIES, ERROR_STATE_LOW_PAPER):
696 if event.printer_name:
697 d = QString(event.printer_name)
699 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
700 device.parseDeviceURI(event.device_uri)
711 self.model = models.normalizeModelUIName(model)
714 d = self.__tr("%1 Printer (%2)").arg(model).arg(idd)
716 elif back_end == 'hpaio':
717 d = self.__tr("%1 Scanner (%2)").arg(model).arg(idd)
719 elif back_end == 'hpfax':
720 d = self.__tr("%1 Fax (%2)").arg(model).arg(idd)
723 d = self.__tr("%1 (%2)").arg(model).arg(idd)
726 if have_pynotify and pynotify.init("hplip"): # Use libnotify/pynotify
727 icon, urgency = ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY.get(error_state,
728 (getPynotifyIcon('info'), pynotify.URGENCY_NORMAL))
730 if event.job_id and event.title:
731 msg = "%s\n%s: %s\n(%s/%s)" % (unicode(d), desc, event.title, event.username, event.job_id)
732 log.debug("Notify: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
733 (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
735 msg = "%s\n%s (%s)" % (unicode(d), desc, event.event_code)
736 log.debug("Notify: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
738 n = pynotify.Notification("HPLIP Device Status", msg, icon)
739 n.set_urgency(urgency)
741 if error_state == ERROR_STATE_ERROR:
742 n.set_timeout(pynotify.EXPIRES_NEVER)
744 n.set_timeout(TRAY_MESSAGE_DELAY)
748 else: # Use "standard" message bubbles
749 icon = ERROR_STATE_TO_ICON.get(error_state, QSystemTrayIcon.Information)
750 if event.job_id and event.title:
751 log.debug("Bubble: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
752 (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
753 self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
754 QString("%1\n%2: %3\n(%4/%5)").\
756 arg(desc).arg(event.title).\
757 arg(event.username).arg(event.job_id),
758 icon, TRAY_MESSAGE_DELAY)
761 log.debug("Bubble: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
762 self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
763 QString("%1\n%2 (%3)").arg(d).\
764 arg(desc).arg(event.event_code),
765 icon, TRAY_MESSAGE_DELAY)
771 def blipTimeout(self):
773 self.tray_icon.setIcon(self.prop_icon)
774 self.active_icon = False
778 def __tr(self, s, c=None):
779 return QApplication.translate("SystemTray", s, c, QApplication.UnicodeUTF8)
784 log.set_module("hp-systray(qt4)")
785 log.debug("PID=%d" % os.getpid())
787 app = SystemTrayApp(sys.argv, read_pipe)
788 app.setQuitOnLastWindowClosed(False) # If not set, settings dlg closes app
792 if QSystemTrayIcon.isSystemTrayAvailable():
797 if not QSystemTrayIcon.isSystemTrayAvailable():
799 QApplication.translate("SystemTray",
800 "<b>No system tray detected on this system.</b><p>Unable to start, exiting.</p>",
801 None, QApplication.UnicodeUTF8),
802 QApplication.translate("SystemTray", "HPLIP Status Service",
803 None, QApplication.UnicodeUTF8))
805 notifier = QSocketNotifier(read_pipe, QSocketNotifier.Read)
806 QObject.connect(notifier, SIGNAL("activated(int)"), app.notifierActivated)