%PDF- %PDF-
| Direktori : /usr/share/hplip/ui5/ |
| Current File : //usr/share/hplip/ui5/systemtray.py |
# -*- coding: utf-8 -*-
#
# (c) Copyright 2003-2015 HP Development Company, L.P.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: Don Welch
# Std Lib
import sys
import struct
import select
import os
import signal
import os.path
import time
# Local
from base.g import *
from base import device, utils, models
from base.codes import *
from .ui_utils import *
# PyQt
try:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
except ImportError:
log.error("Python bindings for Qt4 not found. Try using --qt3. Exiting!")
sys.exit(1)
from .systrayframe import SystrayFrame
# dbus (required)
try:
import dbus
from dbus import SessionBus, lowlevel
except ImportError:
log.error("Python bindings for dbus not found. Exiting!")
sys.exit(1)
import warnings
# Ignore: .../dbus/connection.py:242: DeprecationWarning: object.__init__() takes no parameters
# (occurring on Python 2.6/dBus 0.83/Ubuntu 9.04)
warnings.simplefilter("ignore", DeprecationWarning)
# pynotify (optional)
have_pynotify = True
try:
import notify2 as pynotify
except ImportError:
try:
import pynotify
except ImportError:
have_pynotify = False
TRAY_MESSAGE_DELAY = 10000
HIDE_INACTIVE_DELAY = 5000
BLIP_DELAY = 2000
SET_MENU_DELAY = 1000
MAX_MENU_EVENTS = 10
UPGRADE_CHECK_DELAY=24*60*60*1000 #1 day
#CLEAN_EXEC_DELAY=4*60*60*1000 #4 Hrs
ERROR_STATE_TO_ICON = {
ERROR_STATE_CLEAR: QSystemTrayIcon.Information,
ERROR_STATE_OK: QSystemTrayIcon.Information,
ERROR_STATE_WARNING: QSystemTrayIcon.Warning,
ERROR_STATE_ERROR: QSystemTrayIcon.Critical,
ERROR_STATE_LOW_SUPPLIES: QSystemTrayIcon.Warning,
ERROR_STATE_BUSY: QSystemTrayIcon.Warning,
ERROR_STATE_LOW_PAPER: QSystemTrayIcon.Warning,
ERROR_STATE_PRINTING: QSystemTrayIcon.Information,
ERROR_STATE_SCANNING: QSystemTrayIcon.Information,
ERROR_STATE_PHOTOCARD: QSystemTrayIcon.Information,
ERROR_STATE_FAXING: QSystemTrayIcon.Information,
ERROR_STATE_COPYING: QSystemTrayIcon.Information,
}
if have_pynotify:
info = getPynotifyIcon('info')
warn = getPynotifyIcon('warning')
err = getPynotifyIcon('error')
ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY = {
ERROR_STATE_CLEAR: (info, pynotify.URGENCY_LOW),
ERROR_STATE_OK: (info, pynotify.URGENCY_LOW),
ERROR_STATE_WARNING: (warn, pynotify.URGENCY_NORMAL),
ERROR_STATE_ERROR: (err, pynotify.URGENCY_CRITICAL),
ERROR_STATE_LOW_SUPPLIES: (warn, pynotify.URGENCY_NORMAL),
ERROR_STATE_BUSY: (warn, pynotify.URGENCY_NORMAL),
ERROR_STATE_LOW_PAPER: (warn, pynotify.URGENCY_NORMAL),
ERROR_STATE_PRINTING: (info, pynotify.URGENCY_LOW),
ERROR_STATE_SCANNING: (info, pynotify.URGENCY_LOW),
ERROR_STATE_PHOTOCARD: (info, pynotify.URGENCY_LOW),
ERROR_STATE_FAXING: (info, pynotify.URGENCY_LOW),
ERROR_STATE_COPYING: (info, pynotify.URGENCY_LOW),
}
devices = {} # { <device_uri> : HistoryDevice(), ... }
class DeviceMenu(QMenu):
def __init__(self, title, parent, device_uri, device_hist, index):
QMenu.__init__(self, title, parent)
self.device_uri = device_uri
self.device_hist = device_hist
self.index = index
def update(self):
self.clear()
if self.device_hist:
first = True
for e in self.device_hist:
error_state = STATUS_TO_ERROR_STATE_MAP.get(e.event_code, ERROR_STATE_CLEAR)
ess = device.queryString(e.event_code, 0)
a = QAction(QIcon(getStatusListIcon(error_state)[self.index]),
"%s %s"%(ess,getTimeDeltaDesc(e.timedate)), self)
if first:
f = a.font()
f.setBold(True)
a.setFont(f)
self.setIcon(QIcon(getStatusListIcon(error_state)[self.index]))
first = False
self.addAction(a)
else:
self.addAction(QIcon(load_pixmap("warning", "16x16")),
QApplication.translate("SystemTray", "(No events)", None))
class HistoryDevice(QObject):
def __init__(self, device_uri, needs_update=True):
self.needs_update = needs_update
self.device_uri = device_uri
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
device.parseDeviceURI(device_uri)
if bus == 'usb':
self.id = serial
elif bus == 'net':
self.id = host
elif bus == 'par':
self.id = dev_file
else:
self.id = 'unknown'
self.model = models.normalizeModelUIName(model)
if back_end == 'hp':
self.device_type = DEVICE_TYPE_PRINTER
self.menu_text = self.__tr("%s Printer (%s)"%(self.model,self.id))
elif back_end == 'hpaio':
self.device_type = DEVICE_TYPE_SCANNER
self.menu_text = self.__tr("%s Scanner (%s)"%(self.model,self.id))
elif back_end == 'hpfax':
self.device_type = DEVICE_TYPE_FAX
self.menu_text = self.__tr("%s Fax (%s)"%(self.model,self.id))
else:
self.device_type = DEVICE_TYPE_UNKNOWN
self.menu_text = self.__tr("%s (%s)"%(self.model,self.id))
self.mq = device.queryModelByURI(self.device_uri)
self.index = 0
if self.mq.get('tech-type', TECH_TYPE_NONE) in (TECH_TYPE_MONO_LASER, TECH_TYPE_COLOR_LASER):
self.index = 1
self.history = None
def getHistory(self, service):
if service is not None and self.needs_update:
device_uri, h = service.GetHistory(self.device_uri)
self.history = [device.Event(*tuple(e)) for e in list(h)[:-MAX_MENU_EVENTS:-1]]
self.needs_update = False
def __tr(self, s, c=None):
return QApplication.translate("SystemTray", s, c)
class SystraySettingsDialog(QDialog):
def __init__(self, parent, systray_visible, polling,
polling_interval, systray_messages,
device_list=None,
upgrade_notify=True,
upgrade_pending_time=0,
upgrade_last_update_time=0,
upgrade_msg=""
):
# upgrade_pending_update_time=0,
QDialog.__init__(self, parent)
self.systray_visible = systray_visible
self.systray_messages = systray_messages
if device_list is not None:
self.device_list = device_list
else:
self.device_list = {}
self.polling = polling
self.polling_interval = polling_interval
self.upgrade_notify =upgrade_notify
self.upgrade_last_update_time=upgrade_last_update_time
self.upgrade_pending_time=upgrade_pending_time
self.upgrade_msg=upgrade_msg
self.initUi()
self.SystemTraySettings.updateUi()
def initUi(self):
self.setObjectName("SystraySettingsDialog")
self.resize(QSize(QRect(0,0,488,565).size()).expandedTo(self.minimumSizeHint()))
self.gridlayout = QGridLayout(self)
self.gridlayout.setObjectName("gridlayout")
self.SystemTraySettings = SystrayFrame(self)
self.SystemTraySettings.initUi(self.systray_visible,
self.polling, self.polling_interval,
self.device_list,
self.systray_messages,
self.upgrade_notify,
self.upgrade_pending_time,
self.upgrade_msg)
sizePolicy = QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.SystemTraySettings.sizePolicy().hasHeightForWidth())
self.SystemTraySettings.setSizePolicy(sizePolicy)
self.SystemTraySettings.setFrameShadow(QFrame.Raised)
self.SystemTraySettings.setObjectName("SystemTraySettings")
self.gridlayout.addWidget(self.SystemTraySettings,0,0,1,2)
spacerItem = QSpacerItem(301,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
self.gridlayout.addItem(spacerItem,1,0,1,1)
self.StdButtons = QDialogButtonBox(self)
self.StdButtons.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.NoButton|QDialogButtonBox.Ok)
self.StdButtons.setCenterButtons(False)
self.StdButtons.setObjectName("StdButtons")
self.gridlayout.addWidget(self.StdButtons,1,1,1,1)
# QObject.StdButtons.accepted.connect(self.acceptClicked)
# QObject.StdButtons.rejected.connect(self.reject)
self.StdButtons.accepted.connect(self.acceptClicked)
self.StdButtons.rejected.connect(self.reject)
#QMetaObject.connectSlotsByName(self)
self.setWindowTitle(self.__tr("HP Device Manager - System Tray Settings"))
self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128')))
# pm = load_pixmap("hp_logo", "32x32")
# self.prop_icon = QIcon(pm)
def acceptClicked(self):
self.systray_visible = self.SystemTraySettings.systray_visible
self.polling = self.SystemTraySettings.polling
self.polling_interval = self.SystemTraySettings.polling_interval
self.device_list = self.SystemTraySettings.device_list
self.systray_messages = self.SystemTraySettings.systray_messages
self.upgrade_notify =self.SystemTraySettings.upgrade_notify
self.accept()
def __tr(self, s, c=None):
return QApplication.translate("SystraySettingsDialog", s, c)
class SystemTrayApp(QApplication):
def __init__(self, args, read_pipe):
QApplication.__init__(self, args)
self.menu = None
self.read_pipe = read_pipe
self.fmt = "80s80sI32sI80sf"
self.fmt_size = struct.calcsize(self.fmt)
self.timer_active = False
self.active_icon = False
self.user_settings = UserSettings()
self.user_settings.load()
self.user_settings.debug()
self.tray_icon = QSystemTrayIcon()
pm = load_pixmap("hp_logo", "32x32")
self.prop_icon = QIcon(pm)
a = load_pixmap('active', '16x16')
painter = QPainter(pm)
painter.drawPixmap(32, 0, a)
painter.end()
self.prop_active_icon = QIcon(pm)
self.tray_icon.setIcon(self.prop_icon)
self.session_bus = SessionBus()
self.service = None
for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
self.addDevice(d)
self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
# QObject.tray_icon.messageClicked.connect(self.messageClicked)
self.tray_icon.messageClicked.connect(self.messageClicked)
notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
# QObject.notifier.activated[int].connect(self.notifierActivated)
notifier.activated[int].connect(self.notifierActivated)
# QObject.tray_icon.activated[QSystemTrayIcon::ActivationReason].connect(self.trayActivated)
self.tray_icon.activated["QSystemTrayIcon::ActivationReason"].connect(self.trayActivated)
signal.signal(signal.SIGINT, signal.SIG_DFL)
self.tray_icon.show()
if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
self.tray_icon.setVisible(True)
else:
QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive) # show icon for awhile @ startup
self.tray_icon.setIcon(self.prop_active_icon)
self.active_icon = True
if "--ignore-update-firsttime" not in args:
self.handle_hplip_updation()
QTimer.singleShot(SET_MENU_DELAY, self.initDone)
self.update_timer = QTimer()
# self.update_timer.connect(self.update_timer,SIGNAL("timeout()"),self.handle_hplip_updation)
self.update_timer.timeout.connect(self.handle_hplip_updation)
self.update_timer.start(UPGRADE_CHECK_DELAY)
# Cleans the /var/log/hp/tmp directory
#self.handle_hplip_clean()
#self.clean_timer = QTimer()
#self.clean_timer.connect(self.clean_timer,SIGNAL("timeout()"),self.handle_hplip_clean)
#self.clean_timer.start(CLEAN_EXEC_DELAY)
def initDone(self):
self.tray_icon.setIcon(self.prop_icon)
self.active_icon = False
self.setMenu()
def resetDevice(self):
devices.clear()
def addDevice(self, device_uri):
try:
devices[device_uri]
except KeyError:
devices[device_uri] = HistoryDevice(device_uri)
else:
devices[device_uri].needs_update = True
def handle_hplip_clean(self):
log.debug("handle_hplip_clean ")
home_dir = sys_conf.get('dirs', 'home')
cmd = 'sh %s/hplip_clean.sh'%home_dir
os.system(cmd)
def handle_hplip_updation(self):
log.debug("handle_hplip_updation upgrade_notify =%d"%(self.user_settings.upgrade_notify))
path = utils.which('hp-upgrade')
if self.user_settings.upgrade_notify is False:
log.debug("upgrade notification is disabled in systray ")
if path:
path = os.path.join(path, 'hp-upgrade')
log.debug("Running hp-upgrade: %s " % (path))
# this just updates the available version in conf file. But won't notify
os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--check')
time.sleep(5)
try:
os.waitpid(0, os.WNOHANG)
except OSError:
pass
return
current_time = time.time()
if int(current_time) > self.user_settings.upgrade_pending_update_time:
path = utils.which('hp-upgrade')
if path:
path = os.path.join(path, 'hp-upgrade')
log.debug("Running hp-upgrade: %s " % (path))
os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--notify')
time.sleep(5)
else:
log.error("Unable to find hp-upgrade --notify on PATH.")
else:
log.debug("upgrade schedule time is not yet completed. schedule time =%d current time =%d " %(self.user_settings.upgrade_pending_update_time, current_time))
try:
os.waitpid(0, os.WNOHANG)
except OSError:
pass
def setMenu(self):
self.menu = QMenu()
title = QAction(self.menu)
#title.setDisabled(True)
title.setText(self.__tr("HPLIP Status Service"))
title.setIcon(self.prop_icon)
title.setIconVisibleInMenu(True)
self.menu.insertAction(None, title)
if devices:
if self.service is None:
t = 0
while t < 3:
try:
self.service = self.session_bus.get_object('com.hplip.StatusService',
"/com/hplip/StatusService")
except dbus.DBusException:
log.warn("Unable to connect to StatusService. Retrying...")
t += 1
time.sleep(0.5)
if self.service is not None:
self.menu.addSeparator()
for d in devices:
devices[d].getHistory(self.service)
menu = DeviceMenu(devices[d].menu_text, self.menu, d, devices[d].history, devices[d].index)
self.menu.addMenu(menu)
menu.update()
self.menu.addSeparator()
self.menu.addAction(self.__tr("HP Device Manager..."), self.toolboxTriggered)
self.menu.addSeparator()
self.settings_action = self.menu.addAction(QIcon(load_pixmap('settings', '16x16')),
self.__tr("Settings..."), self.settingsTriggered)
self.menu.addSeparator()
self.menu.addAction(QIcon(load_pixmap('quit', '16x16')), "Quit", self.quitTriggered)
self.tray_icon.setContextMenu(self.menu)
def settingsTriggered(self):
if self.menu is None:
return
self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING)
# sys_conf
cur_vers = sys_conf.get('hplip', 'version')
self.user_settings.load()
installed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_last_update_time))
if utils.Is_HPLIP_older_version(cur_vers, self.user_settings.latest_available_version):
if int(time.time()) < self.user_settings.upgrade_pending_update_time :
postponed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_pending_update_time))
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)
elif self.user_settings.upgrade_last_update_time:
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)
else:
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)
elif self.user_settings.upgrade_last_update_time:
upgrade_msg ="HPLIP-%s version was installed on %s."%(cur_vers, installed_time)
else:
upgrade_msg ="HPLIP-%s version was installed."%(cur_vers)
try:
dlg = SystraySettingsDialog(self.menu, self.user_settings.systray_visible,
self.user_settings.polling, self.user_settings.polling_interval,
self.user_settings.systray_messages,
self.user_settings.polling_device_list,
self.user_settings.upgrade_notify,
self.user_settings.upgrade_pending_update_time,
self.user_settings.upgrade_last_update_time,
upgrade_msg)
if dlg.exec_() == QDialog.Accepted:
self.user_settings.systray_visible = dlg.systray_visible
self.user_settings.systray_messages = dlg.systray_messages
self.user_settings.upgrade_notify = dlg.upgrade_notify
log.debug("HPLIP update notification = %d"%(self.user_settings.upgrade_notify))
self.user_settings.save()
if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
log.debug("Showing...")
self.tray_icon.setVisible(True)
else:
log.debug("Waiting to hide...")
QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)
self.sendMessage('', '', EVENT_USER_CONFIGURATION_CHANGED)
finally:
self.sendMessage('', '', EVENT_DEVICE_START_POLLING)
def timeoutHideWhenInactive(self):
log.debug("Hiding...")
if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
self.tray_icon.setVisible(False)
log.debug("Hidden")
def updateMenu(self):
if self.menu is None:
return
for a in self.menu.actions():
try:
a.menu().update()
except AttributeError:
continue
def trayActivated(self, reason):
if reason == QSystemTrayIcon.Context:
self.updateMenu()
elif reason == QSystemTrayIcon.DoubleClick:
#print "double click"
self.toolboxTriggered()
pass
elif reason == QSystemTrayIcon.Trigger:
#print "single click"
self.updateMenu()
if not self.menu is None:
self.menu.popup(QCursor.pos())
pass
elif reason == QSystemTrayIcon.MiddleClick:
#print "middle click"
pass
def messageClicked(self):
#print "\nPARENT: message clicked"
pass
def quitTriggered(self):
log.debug("Exiting")
self.sendMessage('', '', EVENT_SYSTEMTRAY_EXIT)
self.quit()
del self.tray_icon
def toolboxTriggered(self):
try:
os.waitpid(-1, os.WNOHANG)
except OSError:
pass
# See if it is already running...
ok, lock_file = utils.lock_app('hp-toolbox', True)
if ok: # able to lock, not running...
utils.unlock(lock_file)
path = utils.which('hp-toolbox')
if path:
path = os.path.join(path, 'hp-toolbox')
else:
self.tray_icon.showMessage(self.__tr("HPLIP Status Service"),
self.__tr("Unable to locate hp-toolbox on system PATH."),
QSystemTrayIcon.Critical, TRAY_MESSAGE_DELAY)
log.error("Unable to find hp-toolbox on PATH.")
return
#log.debug(path)
log.debug("Running hp-toolbox: hp-toolbox")
os.spawnlp(os.P_NOWAIT, path, 'hp-toolbox')
else: # ...already running, raise it
self.sendMessage('', '', EVENT_RAISE_DEVICE_MANAGER, interface='com.hplip.Toolbox')
def sendMessage(self, device_uri, printer_name, event_code, username=prop.username,
job_id=0, title='', pipe_name='', interface='com.hplip.StatusService'):
#device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(SessionBus(), interface)
device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(self.session_bus, interface)
def notifierActivated(self, s):
m = ''
while True:
try:
r, w, e = select.select([self.read_pipe], [], [self.read_pipe], 1.0)
except select.error:
log.debug("Error in select()")
break
if e:
log.error("Pipe error: %s" % e)
break
if r:
#m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
m = os.read(self.read_pipe, self.fmt_size)
while len(m) >= self.fmt_size:
event = device.Event(*[x.rstrip(b'\x00').decode('utf-8') if isinstance(x, bytes) else x for x in struct.unpack(self.fmt, m[:self.fmt_size])])
m = m[self.fmt_size:]
if event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:
self.resetDevice()
for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
self.addDevice(d)
self.setMenu()
if event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
log.debug("Re-reading configuration (EVENT_USER_CONFIGURATION_CHANGED)")
self.user_settings.load()
self.user_settings.debug()
elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
self.quit()
return
if self.user_settings.systray_visible in \
(SYSTRAY_VISIBLE_SHOW_ALWAYS, SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE):
log.debug("Showing...")
self.tray_icon.setVisible(True)
if event.event_code == EVENT_DEVICE_UPDATE_ACTIVE:
if not self.active_icon:
self.tray_icon.setIcon(self.prop_active_icon)
self.active_icon = True
continue
elif event.event_code == EVENT_DEVICE_UPDATE_INACTIVE:
if self.active_icon:
self.tray_icon.setIcon(self.prop_icon)
self.active_icon = False
continue
elif event.event_code == EVENT_DEVICE_UPDATE_BLIP:
if not self.active_icon:
self.tray_icon.setIcon(self.prop_active_icon)
self.active_icon = True
QTimer.singleShot(BLIP_DELAY, self.blipTimeout)
continue
if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
log.debug("Waiting to hide...")
QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)
if event.event_code <= EVENT_MAX_USER_EVENT or \
event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:
if event.event_code != EVENT_CUPS_QUEUES_REMOVED:
self.addDevice(event.device_uri)
self.setMenu()
if self.tray_icon.supportsMessages():
log.debug("Tray icon message:")
event.debug()
error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
desc = device.queryString(event.event_code)
show_message = False
if self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ALL: # OK, Busy
show_message = True
elif self.user_settings.systray_messages in (SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS, SYSTRAY_MESSAGES_SHOW_ERRORS_ONLY):
if error_state == ERROR_STATE_ERROR:
show_message = True
elif self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS and \
error_state in (ERROR_STATE_WARNING, ERROR_STATE_LOW_SUPPLIES, ERROR_STATE_LOW_PAPER):
show_message = True
if event.printer_name:
d = event.printer_name
else:
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
device.parseDeviceURI(event.device_uri)
if bus == 'usb':
idd = serial
elif bus == 'net':
idd = host
elif bus == 'par':
idd = dev_file
else:
idd = 'unknown'
self.model = models.normalizeModelUIName(model)
if back_end == 'hp':
d = self.__tr("%s Printer (%s)"%(model,idd))
elif back_end == 'hpaio':
d = self.__tr("%s Scanner (%s)"%(model,idd))
elif back_end == 'hpfax':
d = self.__tr("%s Fax (%s)"%(model,idd))
else:
d = self.__tr("%s (%s)"%(model,idd))
if show_message:
if have_pynotify and pynotify.init("hplip"): # Use libnotify/pynotify
icon, urgency = ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY.get(error_state,
(getPynotifyIcon('info'), pynotify.URGENCY_NORMAL))
if event.job_id and event.title:
msg = "%s\n%s: %s\n(%s/%s)" % (to_unicode(d), desc, event.title, event.username, event.job_id)
log.debug("Notify: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
(event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
else:
msg = "%s\n%s (%s)" % (to_unicode(d), desc, event.event_code)
log.debug("Notify: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
n = pynotify.Notification("HPLIP Device Status", msg, icon)
# CRID: 11833 Debian Traceback error notification exceeded
n.set_hint('transient', True)
n.set_urgency(urgency)
if error_state == ERROR_STATE_ERROR:
n.set_timeout(pynotify.EXPIRES_NEVER)
else:
n.set_timeout(TRAY_MESSAGE_DELAY)
n.show()
else: # Use "standard" message bubbles
icon = ERROR_STATE_TO_ICON.get(error_state, QSystemTrayIcon.Information)
if event.job_id and event.title:
log.debug("Bubble: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
(event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
"%s\n%s: %s\n(%s/%s)"%(d,desc, event.title,event.username,event.job_id),
icon, TRAY_MESSAGE_DELAY)
else:
log.debug("Bubble: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
"%s\n%s (%s)"%(d,desc,event.event_code),
icon, TRAY_MESSAGE_DELAY)
else:
break
# return
def blipTimeout(self):
if self.active_icon:
self.tray_icon.setIcon(self.prop_icon)
self.active_icon = False
def __tr(self, s, c=None):
return QApplication.translate("SystemTray", s, c)
def run(read_pipe):
log.set_module("hp-systray(qt5)")
log.debug("PID=%d" % os.getpid())
try:
app = SystemTrayApp(sys.argv, read_pipe)
except dbus.DBusException as e:
# No session bus
log.debug("Caught exception: %s" % e)
sys.exit(1)
app.setQuitOnLastWindowClosed(False) # If not set, settings dlg closes app
i = 0
while i < 60:
if QSystemTrayIcon.isSystemTrayAvailable():
break
time.sleep(1.0)
i += 1
if QSystemTrayIcon.isSystemTrayAvailable():
notifier = QSocketNotifier(read_pipe, QSocketNotifier.Read)
# QObject.notifier.activated[int].connect(app.notifierActivated)
notifier.activated[int].connect(app.notifierActivated)
app.exec_()