Example #1
0
    def notifier_activated(self, s):
        m = ''
        while True:
            ready = select.select([self.read_pipe], [], [], 1.0)

            if ready[0]:
                m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
                if len(m) == self.fmt_size:
                    event = device.Event(*struct.unpack(self.fmt, m))

                    if event.event_code > EVENT_MAX_USER_EVENT:
                        continue

                    desc = device.queryString(event.event_code)
                    #print "BUBBLE:", event.device_uri, event.event_code, event.username
                    error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
                    icon = self.ERROR_STATE_TO_ICON.get(error_state, self.icon_info)

                    if self.tray_icon.supportsMessages():
                        if event.job_id and event.title:
                            self.tray_icon.showMessage("HPLIP Device Status",
                                QString("%1\n%2\n%3\n(%4/%5/%6)").\
                                arg(event.device_uri).arg(event.event_code).\
                                arg(desc).arg(event.username).arg(event.job_id).arg(event.title),
                                icon, 5000)
                        else:
                            self.tray_icon.showMessage("HPLIP Device Status",
                                QString("%1\n%2\n%3").arg(event.device_uri).\
                                arg(event.event_code).arg(desc),
                                icon, 5000)

            else:
                break
Example #2
0
    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]),
                                    QString("%1 %2").arg(ess).arg(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, QApplication.UnicodeUTF8))
Example #3
0
    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
Example #4
0
    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)])
                while len(m) >= self.fmt_size:
                    event = device.Event(*struct.unpack(self.fmt, m[:self.fmt_size]))

                    m = m[self.fmt_size:]

                    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:
                        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 = QString(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("%1 Printer (%2)").arg(model).arg(idd)

                                elif back_end == 'hpaio':
                                    d = self.__tr("%1 Scanner (%2)").arg(model).arg(idd)

                                elif back_end == 'hpfax':
                                    d = self.__tr("%1 Fax (%2)").arg(model).arg(idd)

                                else:
                                    d = self.__tr("%1 (%2)").arg(model).arg(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)" % (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)" % (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)
                                    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"),
                                            QString("%1\n%2: %3\n(%4/%5)").\
                                            arg(d).\
                                            arg(desc).arg(event.title).\
                                            arg(event.username).arg(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"),
                                            QString("%1\n%2 (%3)").arg(d).\
                                            arg(desc).arg(event.event_code),
                                            icon, TRAY_MESSAGE_DELAY)

            else:
                break
Example #5
0
                            {"width": 20, "margin": 2},  # date/time
                            {"width": 5, "margin": 2},  # code
                            {"width": 40, "margin": 2},  # desc
                            {"width": 8, "margin": 2},  # user
                            {"width": 8, "margin": 2},  # job id
                        )
                    )

                    log.info(log.bold("\nStatus History (most recent first):"))
                    log.info(log.bold(formatter.compose(("Date/Time", "Code", "Status Description", "User", "Job ID"))))
                    log.info(formatter.compose(("-" * 20, "-" * 5, "-" * 40, "-" * 8, "-" * 8)))

                    hq = d.queryHistory()

                    for h in hq:
                        desc = device.queryString(h.event_code)
                        log.info(
                            formatter.compose(
                                (
                                    time.strftime("%x %H:%M:%S", time.localtime(h.timedate)),
                                    str(h.event_code),
                                    desc,
                                    h.username,
                                    str(h.job_id),
                                )
                            )
                        )

                    log.info("")
        finally:
            d.close()
Example #6
0
    def showExitPage(self):
        self.setNextButton(BUTTON_FINISH)
        self.NextButton.setEnabled(False)
        self.CancelButton.setEnabled(True)
        self.SSIDLabel_2.setText(str(self.network))
        self.ip = '0.0.0.0'
        self.hn = ''
        self.success = SUCCESS_NOT_CONNECTED

        beginWaitCursor()
        try:
            try:                
                self.ip,_,addressmode, subnetmask, gateway, pridns, sec_dns= self.wifiObj.getIPConfiguration(self.dev, self.adapterName)
                vsa_codes = self.wifiObj.getVSACodes(self.dev, self.adapterName)
                ss_max, ss_min, ss_val, ss_dbm = self.wifiObj.getSignalStrength(self.dev, self.adapterName,self.network, self.adaptor_id)                 
                self.hn = self.wifiObj.getHostname(self.dev) 
            except Error as e:
                self.showIOError(e)
                return
        finally:
            self.dev.close()
            endWaitCursor()

        if addressmode.lower() == 'dhcp':
            self.success = SUCCESS_CONNECTED

        elif addressmode.lower() == 'autoip':
            self.success = SUCCESS_AUTO_IP

        if self.ip == '0.0.0.0':
            self.success = SUCCESS_NOT_CONNECTED

        self.pages = []

        if self.success == SUCCESS_NOT_CONNECTED:
            self.pages.append((self.__tr("<b>Your printer has not been connected to the wireless network.</b> A valid connection to a wireless network can take up to 2 minutes. This screen will automatically refresh every %s seconds.<p>If your printer fails to connect within a reasonable time, there may be a problem with your configuration." % REFRESH_INTERVAL), load_pixmap('error', '16x16')))
            self.RefreshTimer.start(REFRESH_INTERVAL * 1000)

        elif self.success == SUCCESS_AUTO_IP:
#            self.pages.append((self.__tr("Your printer has been connected to the wireless network, but it has been assigned an address which may not be usable."), load_pixmap('warning', '16x16')))
            self.pages.append((self.__tr("Your printer has been connected to the wireless network and has been assinged a IP. Now run <pre>hp-setup %s</pre>  If IP is not accessible, try again for another IP."%self.ip), load_pixmap('warning', '16x16')))
       #     self.RefreshTimer.start(REFRESH_INTERVAL * 1000)
            self.CancelButton.setEnabled(False)
            self.BackButton.setEnabled(False)
            self.RefreshTimer.stop()

        else: # SUCCESS_CONNECTED
            self.pages.append((self.__tr("Your printer has been successfully configured on the wireless network. You may now unplug the USB cable. To setup the printer, now run <pre>hp-setup %s</pre>"%self.ip), load_pixmap('info', '16x16')))
            self.CancelButton.setEnabled(False)
            self.BackButton.setEnabled(False)
            self.RefreshTimer.stop()

        if addressmode is None:
            self.AddressModeLabel.setText(self.__tr("Unknown"))
        else:
            self.AddressModeLabel.setText(str(addressmode))

        if self.hn is None:
            self.HostnameLabel.setText(self.__tr("Unknown"))
        else:
            self.HostnameLabel.setText(str(self.hn))

        self.IPAddressLabel.setText(str(self.ip))
        self.GatewayLabel.setText(str(gateway))
        self.DNSLabel.setText(str(pridns))
        self.NextButton.setEnabled(True)

        self.SignalStrengthLabel.setText(str("%s/%s (%s dBm)" % (ss_val, ss_max, ss_dbm)))
        self.SignalStrengthIcon.setPixmap(load_pixmap('signal%d' % ss_val, 'other'))

        for c, s in vsa_codes:
            if c :
                ss = s.lower()
                if ss.startswith("info"):
                    pixmap = load_pixmap('info', '16x16')

                elif ss.startswith("warn"):
                    pixmap = load_pixmap('warning', '16x16')

                elif ss.startswith("crit"):
                    pixmap = load_pixmap('error', '16x16')

                else:
                    pixmap = load_pixmap('info', '16x16')

                self.pages.append((device.queryString("vsa_%s" % str(c).zfill(3)), pixmap))

        num_pages = len(self.pages)
        self.PageSpinBox.setMaximum(num_pages)
        self.PageSpinBox.setEnabled(num_pages>1)
        self.PageSpinBox.setValue(1)
        self.PageLabel.setEnabled(num_pages>1)
        self.PageLabel2.setEnabled(num_pages>1)
        self.PageLabel.setText(self.__tr("of %s", str(num_pages)))
        self.page_index = 0
        self.ExitLabel.setText(self.pages[self.page_index][0])
        self.ExitIcon.setPixmap(self.pages[self.page_index][1])
        self.displayPage(PAGE_EXIT)
Example #7
0
    def showExitPage(self):
        self.setNextButton(BUTTON_FINISH)
        self.NextButton.setEnabled(False)
        self.CancelButton.setEnabled(True)
        self.SSIDLabel_2.setText(str(self.network))
        self.ip = '0.0.0.0'
        self.hn = ''
        self.success = SUCCESS_NOT_CONNECTED

        beginWaitCursor()
        try:
            try:                
                self.ip,_,addressmode, subnetmask, gateway, pridns, sec_dns= self.wifiObj.getIPConfiguration(self.dev, self.adapterName)
                if self.ip == "0.0.0.0":
                    self.ip, subnetmask, gateway, pri_dns, sec_dns, addressmode = self.wifiobj.getwifiotherdetails(self.dev,self.adapterName)
                vsa_codes = self.wifiObj.getVSACodes(self.dev, self.adapterName)
                ss_max, ss_min, ss_val, ss_dbm = self.wifiObj.getSignalStrength(self.dev, self.adapterName,self.network, self.adaptor_id)                 
                self.hn = self.wifiObj.getHostname(self.dev) 
            except Error as e:
                self.showIOError(e)
                return
        finally:
            self.dev.close()
            endWaitCursor()

        if 'dhcp' or 'default' in addressmode.lower():
            self.success = SUCCESS_CONNECTED

        elif addressmode.lower() == 'autoip':
            self.success = SUCCESS_AUTO_IP

        if self.ip == '0.0.0.0':
            self.success = SUCCESS_NOT_CONNECTED

        self.pages = []

        if self.success == SUCCESS_NOT_CONNECTED:
            self.pages.append((self.__tr("<b>Your printer has not been connected to the wireless network.</b> A valid connection to a wireless network can take up to 2 minutes. This screen will automatically refresh every %s seconds.<p>If your printer fails to connect within a reasonable time, there may be a problem with your configuration." % REFRESH_INTERVAL), load_pixmap('error', '16x16')))
            self.RefreshTimer.start(REFRESH_INTERVAL * 1000)

        elif self.success == SUCCESS_AUTO_IP:
#            self.pages.append((self.__tr("Your printer has been connected to the wireless network, but it has been assigned an address which may not be usable."), load_pixmap('warning', '16x16')))
            self.pages.append((self.__tr("Your printer has been connected to the wireless network and has been assinged a IP. Now run <pre>hp-setup %s</pre>  If IP is not accessible, try again for another IP."%self.ip), load_pixmap('warning', '16x16')))
       #     self.RefreshTimer.start(REFRESH_INTERVAL * 1000)
            self.CancelButton.setEnabled(False)
            self.BackButton.setEnabled(False)
            self.RefreshTimer.stop()

        else: # SUCCESS_CONNECTED
            self.pages.append((self.__tr("Your printer has been successfully configured on the wireless network. You may now unplug the USB cable. To setup the printer, now run <pre>hp-setup %s</pre>"%self.ip), load_pixmap('info', '16x16')))
            self.CancelButton.setEnabled(False)
            self.BackButton.setEnabled(False)
            self.RefreshTimer.stop()

        if addressmode is None:
            self.AddressModeLabel.setText(self.__tr("Unknown"))
        else:
            self.AddressModeLabel.setText(str(addressmode))

        if self.hn is None:
            self.HostnameLabel.setText(self.__tr("Unknown"))
        else:
            self.HostnameLabel.setText(str(self.hn))

        self.IPAddressLabel.setText(str(self.ip))
        self.GatewayLabel.setText(str(gateway))
        self.DNSLabel.setText(str(pridns))
        self.NextButton.setEnabled(True)

        self.SignalStrengthLabel.setText(str("%s/%s (%s dBm)" % (ss_val, ss_max, ss_dbm)))
        self.SignalStrengthIcon.setPixmap(load_pixmap('signal%d' % ss_val, 'other'))

        for c, s in vsa_codes:
            if c :
                ss = s.lower()
                if ss.startswith("info"):
                    pixmap = load_pixmap('info', '16x16')

                elif ss.startswith("warn"):
                    pixmap = load_pixmap('warning', '16x16')

                elif ss.startswith("crit"):
                    pixmap = load_pixmap('error', '16x16')

                else:
                    pixmap = load_pixmap('info', '16x16')

                self.pages.append((device.queryString("vsa_%s" % str(c).zfill(3)), pixmap))

        num_pages = len(self.pages)
        self.PageSpinBox.setMaximum(num_pages)
        self.PageSpinBox.setEnabled(num_pages>1)
        self.PageSpinBox.setValue(1)
        self.PageLabel.setEnabled(num_pages>1)
        self.PageLabel2.setEnabled(num_pages>1)
        self.PageLabel.setText(self.__tr("of %s", str(num_pages)))
        self.page_index = 0
        self.ExitLabel.setText(self.pages[self.page_index][0])
        self.ExitIcon.setPixmap(self.pages[self.page_index][1])
        self.displayPage(PAGE_EXIT)
Example #8
0
    def updateInfoTable(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.DynamicTableWidget.clear()
        self.DynamicTableWidget.setRowCount(0)
        self.DynamicTableWidget.setColumnCount(0)
        flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled

        while self.TabWidget.count() > 3:
            self.TabWidget.removeTab(3)

        self.DynamicTableWidget.clear()
        self.DynamicTableWidget.setRowCount(0)
        self.DynamicTableWidget.setColumnCount(len(self.headers))
        self.DynamicTableWidget.setHorizontalHeaderLabels(self.headers)

        #
        # Static Data
        #

        try:
            d = device.Device(self.device_uri, None)
        except Error:
            QApplication.restoreOverrideCursor()
            FailureUI(self, self.__tr("<b>Unable to open device %s.</b>"%(self.device_uri)))
            #self.close()
            return

        self.StaticTableWidget.clear()

        self.StaticTableWidget.setColumnCount(len(self.headers))
        self.StaticTableWidget.setHorizontalHeaderLabels(self.headers)

        mq_keys = list(d.mq.keys())
        mq_keys.sort()

        self.StaticTableWidget.setRowCount(len(mq_keys))

        for row, key in enumerate(mq_keys):
            i = QTableWidgetItem(QString(key))
            i.setFlags(flags)
            self.StaticTableWidget.setItem(row, 0, i)

            i = QTableWidgetItem(QString(str(d.mq[key])))
            i.setFlags(flags)
            self.StaticTableWidget.setItem(row, 1, i)

        self.StaticTableWidget.resizeColumnToContents(0)
        self.StaticTableWidget.resizeColumnToContents(1)
        self.StaticTableWidget.setSortingEnabled(True)
        self.StaticTableWidget.sortItems(0)

        #
        # Dynamic Data
        #

        try:
            try:
                d.open()
                d.queryDevice()
            except Error as e:
                QApplication.restoreOverrideCursor()
                FailureUI(self, self.__tr("<b>Unable to open device %s.</b>"%(self.device_uri)))
                #self.close()
                return

            dq_keys = list(d.dq.keys())
            dq_keys.sort()

            self.DynamicTableWidget.setRowCount(len(dq_keys))

            for row, key in enumerate(dq_keys):
                i = QTableWidgetItem(QString(key))
                i.setFlags(flags)
                self.DynamicTableWidget.setItem(row, 0, i)

                i = QTableWidgetItem(QString(str(d.dq[key])))
                i.setFlags(flags)
                self.DynamicTableWidget.setItem(row, 1, i)


            self.DynamicTableWidget.resizeColumnToContents(0)
            self.DynamicTableWidget.resizeColumnToContents(1)
            self.DynamicTableWidget.setSortingEnabled(True)
            self.DynamicTableWidget.sortItems(0)

        finally:
            d.close()

        #
        # History Table
        #

        self.HistoryTableWidget.clear()
        self.HistoryTableWidget.setRowCount(0)

        if d.device_type == DEVICE_TYPE_FAX:
            self.history_headers[1] = self.__tr("Fax")
        else:
            self.history_headers[1] = self.__tr("Printer")

        self.HistoryTableWidget.setColumnCount(len(self.history_headers))
        self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers)

        history = d.queryHistory()
        history.reverse()
        self.HistoryTableWidget.setRowCount(len(history))

        for row, h in enumerate(history):
            dt = QDateTime()
            dt.setTime_t(int(h.timedate))
            dt = value_str(dt)

            ess = device.queryString(h.event_code, 0)

            for col, t in enumerate([dt, h.printer_name,
                           to_unicode(h.event_code), ess,
                           h.username, to_unicode(h.job_id),
                           h.title]):

                i = QTableWidgetItem(QString(t))
                i.setFlags(flags)
                self.HistoryTableWidget.setItem(row, col, i)

        self.HistoryTableWidget.resizeColumnToContents(0)
        self.HistoryTableWidget.resizeColumnToContents(1)
        self.HistoryTableWidget.setSortingEnabled(True)
        self.HistoryTableWidget.sortItems(0)

        #
        # Printer Data
        #

        printers = cups.getPrinters()

        for p in printers:
            if p.device_uri == self.device_uri:
                Tab = QWidget()
                Tab.setObjectName(QString(p.name))

                GridLayout = QGridLayout(Tab)
                GridLayout.setObjectName(QString("GridLayout-%s" % p.name))

                Table = QTableWidget(Tab)
                Table.setAlternatingRowColors(True)
                Table.setSelectionMode(QAbstractItemView.SingleSelection)
                Table.setSelectionBehavior(QAbstractItemView.SelectRows)
                Table.setVerticalScrollMode(QAbstractItemView.ScrollPerItem)
                Table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
                Table.setGridStyle(Qt.DotLine)
                Table.setObjectName(QString("Table-%s" % p.name))
                GridLayout.addWidget(Table, 0, 0, 1, 1)
                self.TabWidget.addTab(Tab, QString(p.name))

                Table.setColumnCount(len(self.headers))
                Table.setHorizontalHeaderLabels(self.headers)

                cups.resetOptions()
                cups.openPPD(p.name)
                current_options = dict(cups.getOptions())

                #current_options['cups_error_log_level'] = cups.getErrorLogLevel()

                try:
                    f = open(os.path.expanduser('~/.cups/lpoptions'))
                except IOError as e:
                    log.debug(str(e))
                    current_options['lpoptions_file_data'] = QString("(%s)"%str(e))
                else:
                    text = f.read()
                    for d in text.splitlines():
                        if p.name in d:
                            current_options['lpoptions_file_data'] = d
                            break
                    else:
                        current_options['lpoptions_file_data'] = self.__tr("(no data)")

                keys = list(current_options.keys())
                keys.sort()

                Table.setRowCount(len(keys))

                for row, key in enumerate(keys):
                    i = QTableWidgetItem(QString(key))
                    i.setFlags(flags)
                    Table.setItem(row, 0, i)

                    if key == 'printer-state':
                        state = int(current_options[key])
                        if state == cups.IPP_PRINTER_STATE_IDLE:
                            i = QTableWidgetItem(self.__tr("idle (%s)"%state))
                        elif state == cups.IPP_PRINTER_STATE_PROCESSING:
                            i = QTableWidgetItem(self.__tr("busy/printing (%s)"%state))
                        elif state == cups.IPP_PRINTER_STATE_STOPPED:
                            i = QTableWidgetItem(self.__tr("stopped (%s)"%state))
                        else:
                            i = QTableWidgetItem(QString(str(state)))
                    else:
                        i = QTableWidgetItem(QString(str(current_options[key])))

                    i.setFlags(flags)
                    Table.setItem(row, 1, i)

                Table.resizeColumnToContents(0)
                Table.resizeColumnToContents(1)
                Table.setSortingEnabled(True)
                Table.sortItems(0)

        cups.closePPD()
        self.TabWidget.setCurrentIndex(0)
        QApplication.restoreOverrideCursor()
Example #9
0
    def updateInfoTable(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.DynamicTableWidget.clear()
        self.DynamicTableWidget.setRowCount(0)
        self.DynamicTableWidget.setColumnCount(0)
        flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled

        while self.TabWidget.count() > 3:
            self.TabWidget.removeTab(3)

        self.DynamicTableWidget.clear()
        self.DynamicTableWidget.setRowCount(0)
        self.DynamicTableWidget.setColumnCount(len(self.headers))
        self.DynamicTableWidget.setHorizontalHeaderLabels(self.headers)

        #
        # Static Data
        #

        try:
            d = device.Device(self.device_uri, None)
        except Error:
            QApplication.restoreOverrideCursor()
            FailureUI(
                self,
                self.__tr("<b>Unable to open device %s.</b>" %
                          (self.device_uri)))
            #self.close()
            return

        self.StaticTableWidget.clear()

        self.StaticTableWidget.setColumnCount(len(self.headers))
        self.StaticTableWidget.setHorizontalHeaderLabels(self.headers)

        mq_keys = list(d.mq.keys())
        mq_keys.sort()

        self.StaticTableWidget.setRowCount(len(mq_keys))

        for row, key in enumerate(mq_keys):
            i = QTableWidgetItem(str(key))
            i.setFlags(flags)
            self.StaticTableWidget.setItem(row, 0, i)

            i = QTableWidgetItem(str(d.mq[key]))
            i.setFlags(flags)
            self.StaticTableWidget.setItem(row, 1, i)

        self.StaticTableWidget.resizeColumnToContents(0)
        self.StaticTableWidget.resizeColumnToContents(1)
        self.StaticTableWidget.setSortingEnabled(True)
        self.StaticTableWidget.sortItems(0)

        #
        # Dynamic Data
        #

        try:
            try:
                d.open()
                d.queryDevice()
            except Error as e:
                QApplication.restoreOverrideCursor()
                FailureUI(
                    self,
                    self.__tr("<b>Unable to open device %s.</b>" %
                              (self.device_uri)))
                #self.close()
                return

            dq_keys = list(d.dq.keys())
            dq_keys.sort()

            self.DynamicTableWidget.setRowCount(len(dq_keys))

            for row, key in enumerate(dq_keys):
                i = QTableWidgetItem(str(key))
                i.setFlags(flags)
                self.DynamicTableWidget.setItem(row, 0, i)

                i = QTableWidgetItem(str(d.dq[key]))
                i.setFlags(flags)
                self.DynamicTableWidget.setItem(row, 1, i)

            self.DynamicTableWidget.resizeColumnToContents(0)
            self.DynamicTableWidget.resizeColumnToContents(1)
            self.DynamicTableWidget.setSortingEnabled(True)
            self.DynamicTableWidget.sortItems(0)

        finally:
            d.close()

        #
        # History Table
        #

        self.HistoryTableWidget.clear()
        self.HistoryTableWidget.setRowCount(0)

        if d.device_type == DEVICE_TYPE_FAX:
            self.history_headers[1] = self.__tr("Fax")
        else:
            self.history_headers[1] = self.__tr("Printer")

        self.HistoryTableWidget.setColumnCount(len(self.history_headers))
        self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers)

        history = d.queryHistory()
        history.reverse()
        self.HistoryTableWidget.setRowCount(len(history))

        for row, h in enumerate(history):
            dt = QDateTime()
            dt.setTime_t(int(h.timedate))
            dt = value_str(dt)

            ess = device.queryString(h.event_code, 0)

            for col, t in enumerate([
                    dt, h.printer_name,
                    to_unicode(h.event_code), ess, h.username,
                    to_unicode(h.job_id), h.title
            ]):

                i = QTableWidgetItem(str(t))
                i.setFlags(flags)
                self.HistoryTableWidget.setItem(row, col, i)

        self.HistoryTableWidget.resizeColumnToContents(0)
        self.HistoryTableWidget.resizeColumnToContents(1)
        self.HistoryTableWidget.setSortingEnabled(True)
        self.HistoryTableWidget.sortItems(0)

        #
        # Printer Data
        #

        printers = cups.getPrinters()

        for p in printers:
            if p.device_uri == self.device_uri:
                Tab = QWidget()
                Tab.setObjectName(str(p.name))

                GridLayout = QGridLayout(Tab)
                GridLayout.setObjectName(str("GridLayout-%s" % p.name))

                Table = QTableWidget(Tab)
                Table.setAlternatingRowColors(True)
                Table.setSelectionMode(QAbstractItemView.SingleSelection)
                Table.setSelectionBehavior(QAbstractItemView.SelectRows)
                Table.setVerticalScrollMode(QAbstractItemView.ScrollPerItem)
                Table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
                Table.setGridStyle(Qt.DotLine)
                Table.setObjectName(str("Table-%s" % p.name))
                GridLayout.addWidget(Table, 0, 0, 1, 1)
                self.TabWidget.addTab(Tab, str(p.name))

                Table.setColumnCount(len(self.headers))
                Table.setHorizontalHeaderLabels(self.headers)

                cups.resetOptions()
                cups.openPPD(p.name)
                current_options = dict(cups.getOptions())

                #current_options['cups_error_log_level'] = cups.getErrorLogLevel()

                try:
                    f = open(os.path.expanduser('~/.cups/lpoptions'))
                except IOError as e:
                    log.debug(str(e))
                    current_options['lpoptions_file_data'] = str("(%s)" %
                                                                 str(e))
                else:
                    text = f.read()
                    for d in text.splitlines():
                        if p.name in d:
                            current_options['lpoptions_file_data'] = d
                            break
                    else:
                        current_options['lpoptions_file_data'] = self.__tr(
                            "(no data)")

                keys = list(current_options.keys())
                keys.sort()

                Table.setRowCount(len(keys))

                for row, key in enumerate(keys):
                    i = QTableWidgetItem(str(key))
                    i.setFlags(flags)
                    Table.setItem(row, 0, i)

                    if key == 'printer-state':
                        state = int(current_options[key])
                        if state == cups.IPP_PRINTER_STATE_IDLE:
                            i = QTableWidgetItem(self.__tr("idle (%s)" %
                                                           state))
                        elif state == cups.IPP_PRINTER_STATE_PROCESSING:
                            i = QTableWidgetItem(
                                self.__tr("busy/printing (%s)" % state))
                        elif state == cups.IPP_PRINTER_STATE_STOPPED:
                            i = QTableWidgetItem(
                                self.__tr("stopped (%s)" % state))
                        else:
                            i = QTableWidgetItem(str(state))
                    else:
                        i = QTableWidgetItem(str(current_options[key]))

                    i.setFlags(flags)
                    Table.setItem(row, 1, i)

                Table.resizeColumnToContents(0)
                Table.resizeColumnToContents(1)
                Table.setSortingEnabled(True)
                Table.sortItems(0)

        cups.closePPD()
        self.TabWidget.setCurrentIndex(0)
        QApplication.restoreOverrideCursor()
Example #10
0
        else:
            self.history_headers[1] = self.__tr("Printer")

        self.HistoryTableWidget.setColumnCount(len(self.history_headers))
        self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers)

        history = d.queryHistory()
        history.reverse()
        self.HistoryTableWidget.setRowCount(len(history))

        for row, h in enumerate(history):
            dt = QDateTime()
            dt.setTime_t(int(h.timedate))
            dt = dt.toString()

            ess = device.queryString(h.event_code, 0)

            for col, t in enumerate([
                    dt, h.printer_name,
                    unicode(h.event_code), ess, h.username,
                    unicode(h.job_id), h.title
            ]):

                i = QTableWidgetItem(QString(t))
                i.setFlags(flags)
                self.HistoryTableWidget.setItem(row, col, i)

        self.HistoryTableWidget.resizeColumnToContents(0)
        self.HistoryTableWidget.resizeColumnToContents(1)
        self.HistoryTableWidget.setSortingEnabled(True)
        self.HistoryTableWidget.sortItems(0)
Example #11
0
                    ))

                    log.info(log.bold("\nStatus History (most recent first):"))
                    log.info(
                        log.bold(
                            formatter.compose(
                                ("Date/Time", "Code", "Status Description",
                                 "User", "Job ID"))))
                    log.info(
                        formatter.compose(
                            ('-' * 20, '-' * 5, '-' * 40, '-' * 8, '-' * 8)))

                    hq = d.queryHistory()

                    for h in hq:
                        desc = device.queryString(h.event_code)
                        log.info(
                            formatter.compose(
                                (time.strftime("%x %H:%M:%S",
                                               time.localtime(h.timedate)),
                                 str(h.event_code), desc, h.username,
                                 str(h.job_id))))

                    log.info("")
        finally:
            d.close()

    else:  # GUI mode
        QApplication, ui_package = utils.import_dialog(ui_toolkit)
        ui = import_module(ui_package + ".infodialog")
Example #12
0
        else:
            self.history_headers[1] = self.__tr("Printer")

        self.HistoryTableWidget.setColumnCount(len(self.history_headers))
        self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers)

        history = d.queryHistory()
        history.reverse()
        self.HistoryTableWidget.setRowCount(len(history))

        for row, h in enumerate(history):
            dt = QDateTime()
            dt.setTime_t(int(h.timedate))
            dt = dt.toString()

            ess = device.queryString(h.event_code, 0)

            for col, t in enumerate([dt, h.printer_name,
                           unicode(h.event_code), ess,
                           h.username, unicode(h.job_id),
                           h.title]):

                i = QTableWidgetItem(QString(t))
                i.setFlags(flags)
                self.HistoryTableWidget.setItem(row, col, i)

        self.HistoryTableWidget.resizeColumnToContents(0)
        self.HistoryTableWidget.resizeColumnToContents(1)
        self.HistoryTableWidget.setSortingEnabled(True)
        self.HistoryTableWidget.sortItems(0)
Example #13
0
    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_ERROR_NO_PROBED_DEVICES_FOUND:
                        newmsg = "HPLIP cannot detect devices in your network. This may be due to existing firewall settings blocking the required ports like (5353/udp). When you are in a trusted network environment, you may open the ports for network services like mdns and slp in the firewall. For detailed steps follow the link.\n\n http://hplipopensource.com/node/375"
                        FailureUI(None, newmsg, "")
                        continue
                    
                    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 = QString(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"),
                                            QString("%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"),
                                            QString("%s\n%s (%s)"%(d,desc,event.event_code)),
                                            icon, TRAY_MESSAGE_DELAY)

            else:
                break