# -*- coding: utf-8 -*- # # (c) Copyright 2001-2009 Hewlett-Packard 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 # # Authors: Don Welch, Naga Samrat Chowdary Narla # #from __future__ import generators # Std Lib import sys import time import os import gzip import select import struct # Local from base.g import * from base import device, utils, pml, maint, models, pkit from prnt import cups from base.codes import * from ui_utils import * import hpmudext from installer.core_install import * # Qt from PyQt4.QtCore import * from PyQt4.QtGui import * # dbus try: import dbus from dbus.mainloop.qt import DBusQtMainLoop from dbus import lowlevel except ImportError: log.error("Unable to load DBus libraries. Please check your installation and try again.") 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) # Main form from devmgr5_base import Ui_MainWindow # Aux. dialogs from faxsetupdialog import FaxSetupDialog from plugindialog import PluginDialog from firmwaredialog import FirmwareDialog from aligndialog import AlignDialog from printdialog import PrintDialog from makecopiesdialog import MakeCopiesDialog from sendfaxdialog import SendFaxDialog from fabwindow import FABWindow from devicesetupdialog import DeviceSetupDialog from printtestpagedialog import PrintTestPageDialog from infodialog import InfoDialog from cleandialog import CleanDialog from colorcaldialog import ColorCalDialog from linefeedcaldialog import LineFeedCalDialog from pqdiagdialog import PQDiagDialog from nodevicesdialog import NoDevicesDialog from aboutdialog import AboutDialog # Other forms and controls from settingsdialog import SettingsDialog from printsettingstoolbox import PrintSettingsToolbox # all in seconds MIN_AUTO_REFRESH_RATE = 5 MAX_AUTO_REFRESH_RATE = 60 DEF_AUTO_REFRESH_RATE = 30 device_list = {} # { Device_URI : device.Device(), ... } model_obj = models.ModelData() # Used to convert dbus xformed data back to plain Python types # *********************************************************************************** # # ITEM/UTILITY UI CLASSES # # *********************************************************************************** class FuncViewItem(QListWidgetItem): def __init__(self, parent, text, pixmap, tooltip_text, cmd): QListWidgetItem.__init__(self, QIcon(pixmap), text, parent) self.tooltip_text = tooltip_text self.cmd = cmd # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX class DeviceViewItem(QListWidgetItem): def __init__(self, parent, text, pixmap, device_uri, is_avail=True): QListWidgetItem.__init__(self, QIcon(pixmap), text, parent) self.device_uri = device_uri self.is_avail = is_avail self.setTextAlignment(Qt.AlignHCenter) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX class PluginInstall(QObject): def __init__(self, parent, plugin_type, plugin_installed): self.parent = parent self.plugin_type = plugin_type self.plugin_installed = plugin_installed def exec_(self): install_plugin = True if self.plugin_installed: install_plugin = QMessageBox.warning(self.parent, self.parent.windowTitle(), self.__tr("The HPLIP plugin is already installed.
Do you want to continue and re-install it?"), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton) == QMessageBox.Yes if install_plugin: ok, sudo_ok = pkit.run_plugin_command(self.plugin_type == PLUGIN_REQUIRED, self.parent.cur_device.mq['plugin-reason']) if not sudo_ok: QMessageBox.critical(self.parent, self.parent.windowTitle(), self.__tr("Unable to find an appropriate su/sudo utility to run hp-plugin.
Install kdesu, gnomesu, or gksu.
"), QMessageBox.Ok, QMessageBox.NoButton, QMessageBox.NoButton) def __tr(self,s,c = None): return qApp.translate("DevMgr5",s,c) class DiagnoseQueue(QObject): def __init__(self, parent): self.parent = parent def exec_(self): ok, output = utils.run('hp-diagnose_queues -r') def __tr(self,s,c = None): return qApp.translate("DevMgr5",s,c) # *********************************************************************************** # # MAINWINDOW # # *********************************************************************************** class DevMgr5(QMainWindow, Ui_MainWindow): def __init__(self, toolbox_version, initial_device_uri=None, dbus_loop=None, parent=None, name=None, fl=0): QMainWindow.__init__(self, parent) log.debug("Initializing toolbox UI (Qt4)...") log.debug("HPLIP Version: %s" % prop.installed_version) self.toolbox_version = toolbox_version self.initial_device_uri = initial_device_uri self.device_vars = {} self.num_devices = 0 self.cur_device = None self.cur_printer = None self.updating = False self.init_failed = False self.service = None self.Is_autoInstaller_distro = False # True-->tier1(supports auto installation). False--> tier2(manual installation) # Distro insformation core = CoreInstall(MODE_CHECK) # core.init() self.Is_autoInstaller_distro = core.is_auto_installer_support() # User settings self.user_settings = UserSettings() self.user_settings.load() self.user_settings.debug() self.cur_device_uri = self.user_settings.last_used_device_uri installed_version=sys_conf.get('hplip','version') if not utils.Is_HPLIP_older_version( installed_version, self.user_settings.latest_available_version): self.setupUi(self,"",self.Is_autoInstaller_distro) else: self.setupUi(self, self.user_settings.latest_available_version,self.Is_autoInstaller_distro) # Other initialization self.initDBus() self.initPixmaps() self.initMisc() self.initUI() cups.setPasswordCallback(showPasswordUI) if not prop.doc_build: self.ContentsAction.setEnabled(False) self.allow_auto_refresh = True QTimer.singleShot(0, self.initalUpdate) # *********************************************************************************** # # INIT # # *********************************************************************************** # TODO: Make sbus init mandatory success, else exit def initDBus(self): self.dbus_loop = DBusQtMainLoop(set_as_default=True) self.dbus_avail, self.service, self.session_bus = device.init_dbus(self.dbus_loop) if not self.dbus_avail: log.error("dBus initialization error. Exiting.") self.init_failed = True return # Receive events from the session bus self.session_bus.add_signal_receiver(self.handleSessionSignal, sender_keyword='sender', destination_keyword='dest', interface_keyword='interface', member_keyword='member', path_keyword='path') def initPixmaps(self): self.func_icons_cached = False self.func_icons = {} self.device_icons = {} # Application icon self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128'))) self.fax_icon = load_pixmap("fax2", "other") def initUI(self): # Setup device icon list self.DeviceList.setSortingEnabled(True) self.DeviceList.setContextMenuPolicy(Qt.CustomContextMenu) self.setDeviceListViewMode(QListView.IconMode) self.connect(self.ViewAsIconsAction, SIGNAL("triggered()"), lambda: self.setDeviceListViewMode(QListView.IconMode)) self.connect(self.ViewAsListAction, SIGNAL("triggered()"), lambda: self.setDeviceListViewMode(QListView.ListMode)) self.connect(self.DeviceList, SIGNAL("customContextMenuRequested(const QPoint &)"), self.DeviceList_customContextMenuRequested) # Setup main menu self.DeviceRefreshAction.setIcon(QIcon(load_pixmap("refresh1", "16x16"))) self.connect(self.DeviceRefreshAction, SIGNAL("triggered()"), self.DeviceRefreshAction_activated) self.RefreshAllAction.setIcon(QIcon(load_pixmap("refresh", "16x16"))) self.connect(self.RefreshAllAction, SIGNAL("triggered()"), self.RefreshAllAction_activated) self.SetupDeviceAction.setIcon(QIcon(load_pixmap('list_add', '16x16'))) self.connect(self.SetupDeviceAction, SIGNAL("triggered()"), self.SetupDeviceAction_activated) self.RemoveDeviceAction.setIcon(QIcon(load_pixmap('list_remove', '16x16'))) self.connect(self.RemoveDeviceAction, SIGNAL("triggered()"), self.RemoveDeviceAction_activated) self.PreferencesAction.setIcon(QIcon(load_pixmap('settings', '16x16'))) self.connect(self.PreferencesAction, SIGNAL("triggered()"), self.PreferencesAction_activated) self.ContentsAction.setIcon(QIcon(load_pixmap("help", "16x16"))) self.connect(self.ContentsAction, SIGNAL("triggered()"), self.helpContents) self.QuitAction.setIcon(QIcon(load_pixmap("quit", "16x16"))) self.connect(self.QuitAction, SIGNAL("triggered()"), self.quit) self.connect(self.AboutAction, SIGNAL("triggered()"), self.helpAbout) self.connect(self.PrintControlPrinterNameCombo, SIGNAL("activated(const QString &)"), self.PrintControlPrinterNameCombo_activated) self.connect(self.PrintSettingsPrinterNameCombo, SIGNAL("activated(const QString &)"), self.PrintSettingsPrinterNameCombo_activated) # Init tabs/controls self.initActionsTab() self.initStatusTab() self.initSuppliesTab() self.initPrintSettingsTab() self.initPrintControlTab() self.connect(self.Tabs,SIGNAL("currentChanged(int)"),self.Tabs_currentChanged) # Resize the splitter so that the device list starts as a single column self.splitter.setSizes([80, 600]) # Setup the Device List self.DeviceList.setIconSize(QSize(60, 60)) self.connect(self.DeviceList, SIGNAL("currentItemChanged(QListWidgetItem * ,QListWidgetItem *)"), self.DeviceList_currentChanged) def initMisc(self): self.TabIndex = { 0: self.updateActionsTab, 1: self.updateStatusTab, 2: self.updateSuppliesTab, 3: self.updatePrintSettingsTab, 4: self.updatePrintControlTab, 5:self.updateHPLIPupgrade, } # docs self.docs = "http://hplip.sf.net" if prop.doc_build: g = os.path.join(sys_conf.get('dirs', 'doc'), 'index.html') if os.path.exists(g): self.docs = "file://%s" % g # support self.support = "https://launchpad.net/hplip" def initalUpdate(self): if self.init_failed: self.close() return self.rescanDevices() cont = True if self.initial_device_uri is not None: if not self.activateDevice(self.initial_device_uri): log.error("Device %s not found" % self.initial_device_uri) cont = False if self.cur_printer: self.getPrinterState() if self.printer_state == cups.IPP_PRINTER_STATE_STOPPED: self.cur_device.sendEvent(EVENT_PRINTER_QUEUE_STOPPED, self.cur_printer) if not self.printer_accepting: self.cur_device.sendEvent(EVENT_PRINTER_QUEUE_REJECTING_JOBS, self.cur_printer) def activateDevice(self, device_uri): log.debug(log.bold("Activate: %s %s %s" % ("*"*20, device_uri, "*"*20))) index = 0 d = self.DeviceList.item(index) #firstItem() found = False while d is not None: if d.device_uri == device_uri: found = True self.DeviceList.setSelected(d, True) self.DeviceList.setCurrentItem(d) break index += 1 d = self.DeviceList.item(index) return found # *********************************************************************************** # # UPDATES/NOTIFICATIONS # # *********************************************************************************** def handleSessionSignal(self, *args, **kwds): if kwds['interface'] == 'com.hplip.Toolbox' and \ kwds['member'] == 'Event': log.debug("Handling event...") event = device.Event(*args[:6]) event.debug() if event.event_code < EVENT_MIN_USER_EVENT: pass elif event.event_code == EVENT_DEVICE_UPDATE_REPLY: log.debug("EVENT_DEVICE_UPDATE_REPLY (%s)" % event.device_uri) dev = self.findDeviceByURI(event.device_uri) if dev is not None: try: self.service.GetStatus(event.device_uri, reply_handler=self.handleStatusReply, error_handler=self.handleStatusError) except dbus.exceptions.DBusException, e: log.error("dbus call to GetStatus() failed.") elif event.event_code == EVENT_USER_CONFIGURATION_CHANGED: log.debug("EVENT_USER_CONFIGURATION_CHANGED") self.user_settings.load() elif event.event_code == EVENT_HISTORY_UPDATE: log.debug("EVENT_HISTORY_UPDATE (%s)" % event.device_uri) dev = self.findDeviceByURI(event.device_uri) if dev is not None: self.updateHistory(dev) elif event.event_code == EVENT_SYSTEMTRAY_EXIT: log.debug("EVENT_SYSTEMTRAY_EXIT") log.error("HPLIP Status Service was closed. HPLIP Device Manager will now exit.") self.close() elif event.event_code == EVENT_RAISE_DEVICE_MANAGER: log.debug("EVENT_RAISE_DEVICE_MANAGER") self.showNormal() self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self.raise_() elif event.event_code in (EVENT_DEVICE_START_POLLING, EVENT_DEVICE_STOP_POLLING, EVENT_POLLING_REQUEST): pass else: log.error("Unhandled event: %d" % event.event_code) def handleStatusReply(self, device_uri, data): dev = self.findDeviceByURI(device_uri) if dev is not None: t = {} for key in data: value = model_obj.convert_data(str(key), str(data[key])) t.setdefault(key, value) dev.dq = t.copy() for d in dev.dq: dev.__dict__[d.replace('-','_')] = dev.dq[d] self.updateDevice(dev) def handleStatusError(self, e): log.error(str(e)) def updateHistory(self, dev=None): if dev is None: dev = self.cur_device try: self.service.GetHistory(dev.device_uri, reply_handler=self.handleHistoryReply, error_handler=self.handleHistoryError) except dbus.exceptions.DBusException, e: log.error("dbus call to GetHistory() failed.") def handleHistoryReply(self, device_uri, history): dev = self.findDeviceByURI(device_uri) if dev is not None: result = [] history.reverse() for h in history: result.append(device.Event(*tuple(h))) try: self.error_code = result[0].event_code except IndexError: self.error_code = STATUS_UNKNOWN dev.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.error_code, ERROR_STATE_CLEAR) dev.hist = result self.updateDevice(dev) def handleHistoryError(self, e): log.error(str(e)) def sendMessage(self, device_uri, printer_name, event_code, username=prop.username, job_id=0, title=''): device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(self.session_bus) def timedRefresh(self): if not self.updating and self.user_settings.auto_refresh and self.allow_auto_refresh: log.debug("Refresh timer...") self.cleanupChildren() if self.user_settings.auto_refresh_type == 0: self.requestDeviceUpdate() else: self.rescanDevices() # *********************************************************************************** # # TAB/DEVICE CHANGE SLOTS # # *********************************************************************************** def Tabs_currentChanged(self, tab=0): """ Called when the active tab changes. Update newly displayed tab. """ if self.cur_device is not None: self.TabIndex[tab]() def updateAllTabs(self): for tab in self.TabIndex: self.TabIndex[tab]() def updateCurrentTab(self): log.debug("updateCurrentTab()") self.TabIndex[self.Tabs.currentIndex()]() # *********************************************************************************** # # DEVICE ICON LIST/DEVICE UPDATE(S) # # *********************************************************************************** def DeviceRefreshAction_activated(self): self.DeviceRefreshAction.setEnabled(False) self.requestDeviceUpdate() self.DeviceRefreshAction.setEnabled(True) def RefreshAllAction_activated(self): self.rescanDevices() def setDeviceListViewMode(self, mode): if mode == QListView.ListMode: self.DeviceList.setViewMode(QListView.ListMode) self.ViewAsListAction.setEnabled(False) self.ViewAsIconsAction.setEnabled(True) else: self.DeviceList.setViewMode(QListView.IconMode) self.ViewAsListAction.setEnabled(True) self.ViewAsIconsAction.setEnabled(False) def createDeviceIcon(self, dev=None): if dev is None: dev = self.cur_device try: dev.icon except AttributeError: dev.icon = "default_printer" try: self.device_icons[dev.icon] except: self.device_icons[dev.icon] = load_pixmap(dev.icon, 'devices') pix = self.device_icons[dev.icon] w, h = pix.width(), pix.height() error_state = dev.error_state icon = QPixmap(w, h) p = QPainter(icon) p.eraseRect(0, 0, icon.width(), icon.height()) p.drawPixmap(0, 0, pix) try: tech_type = dev.tech_type except AttributeError: tech_type = TECH_TYPE_NONE if dev.device_type == DEVICE_TYPE_FAX: p.drawPixmap(w - self.fax_icon.width(), 0, self.fax_icon) if error_state != ERROR_STATE_CLEAR: if tech_type in (TECH_TYPE_COLOR_INK, TECH_TYPE_MONO_INK): status_icon = getStatusOverlayIcon(error_state)[0] # ink else: status_icon = getStatusOverlayIcon(error_state)[1] # laser if status_icon is not None: p.drawPixmap(0, 0, status_icon) p.end() return icon def refreshDeviceList(self): global devices log.debug("Rescanning device list...") if 1: beginWaitCursor() self.updating = True self.setWindowTitle(self.__tr("Refreshing Device List - HP Device Manager")) self.statusBar().showMessage(self.__tr("Refreshing device list...")) self.cups_devices = device.getSupportedCUPSDevices(['hp', 'hpfax']) current = None try: adds = [] for d in self.cups_devices: if d not in device_list: adds.append(d) log.debug("Adds: %s" % ','.join(adds)) removals = [] for d in device_list: if d not in self.cups_devices: removals.append(d) log.debug("Removals (1): %s" % ','.join(removals)) updates = [] for d in device_list: if d not in adds and d not in removals: updates.append(d) log.debug("Updates: %s" % ','.join(updates)) for d in adds: log.debug("adding: %s" % d) # Note: Do not perform any I/O with this device. dev = device.Device(d, service=self.service, disable_dbus=False) if not dev.supported: log.debug("Unsupported model - removing device.") removals.append(d) continue icon = self.createDeviceIcon(dev) if dev.device_type == DEVICE_TYPE_FAX: DeviceViewItem(self.DeviceList, self.__tr("%1 (Fax)").arg(dev.model_ui), icon, d) else: if dev.fax_type: DeviceViewItem(self.DeviceList, self.__tr("%1 (Printer)").arg(dev.model_ui), icon, d) else: DeviceViewItem(self.DeviceList, dev.model_ui, icon, d) device_list[d] = dev log.debug("Removals (2): %s" % ','.join(removals)) for d in removals: index = self.DeviceList.count()-1 item = self.DeviceList.item(index) log.debug("removing: %s" % d) try: del device_list[d] except KeyError: pass while index >= 0 and item is not None: if item.device_uri == d: self.DeviceList.takeItem(index) break index -= 1 item = self.DeviceList.item(index) qApp.processEvents() self.DeviceList.updateGeometry() qApp.processEvents() if len(device_list): for tab in self.TabIndex: self.Tabs.setTabEnabled(tab, True) if self.cur_device_uri: index = 0 item = first_item = self.DeviceList.item(index) while item is not None: qApp.processEvents() if item.device_uri == self.cur_device_uri: current = item self.statusBar().showMessage(self.cur_device_uri) break index += 1 item = self.DeviceList.item(index) else: self.cur_device = None self.cur_device_uri = '' if self.cur_device is None: i = self.DeviceList.item(0) if i is not None: self.cur_device_uri = i.device_uri self.cur_device = device_list[self.cur_device_uri] current = i self.updatePrinterCombos() if self.cur_device_uri: #user_conf.set('last_used', 'device_uri',self.cur_device_uri) self.user_settings.last_used_device_uri = self.cur_device_uri self.user_settings.save() for d in updates + adds: if d not in removals: self.requestDeviceUpdate(device_list[d]) else: # no devices self.cur_device = None self.DeviceRefreshAction.setEnabled(False) self.RemoveDeviceAction.setEnabled(False) self.updating = False self.statusBar().showMessage(self.__tr("Press F6 to refresh.")) for tab in self.TabIndex: self.Tabs.setTabEnabled(tab, False) endWaitCursor() dlg = NoDevicesDialog(self) dlg.exec_() finally: self.updating = False endWaitCursor() if current is not None: self.DeviceList.setCurrentItem(current) self.DeviceRefreshAction.setEnabled(True) if self.cur_device is not None: self.RemoveDeviceAction.setEnabled(True) self.statusBar().showMessage(self.cur_device_uri) self.updateWindowTitle() def updateWindowTitle(self): if self.cur_device.device_type == DEVICE_TYPE_FAX: self.setWindowTitle(self.__tr("HP Device Manager - %1 (Fax)").arg(self.cur_device.model_ui)) else: if self.cur_device.fax_type: self.setWindowTitle(self.__tr("HP Device Manager - %1 (Printer)").arg(self.cur_device.model_ui)) else: self.setWindowTitle(self.__tr("HP Device Manager - %1").arg(self.cur_device.model_ui)) self.statusBar().showMessage(self.cur_device_uri) def updateDeviceByURI(self, device_uri): return self.updateDevice(self.findDeviceByURI(device_uri)) def updateDevice(self, dev=None, update_tab=True): """ Update the device icon and currently displayed tab. """ if dev is None: dev = self.cur_device log.debug("updateDevice(%s)" % dev.device_uri) item = self.findItem(dev) if item is not None: item.setIcon(QIcon(self.createDeviceIcon(dev))) if dev is self.cur_device and update_tab: self.updatePrinterCombos() self.updateCurrentTab() self.statusBar().showMessage(self.cur_device_uri) def DeviceList_currentChanged(self, i, j): if i is not None and not self.updating: self.cur_device_uri = self.DeviceList.currentItem().device_uri self.cur_device = device_list[self.cur_device_uri] #user_conf.set('last_used', 'device_uri', self.cur_device_uri) self.user_settings.last_used_device_uri = self.cur_device_uri self.user_settings.save() self.updateDevice() self.updateWindowTitle() def findItem(self, dev): if dev is None: dev = self.cur_device return self.findItemByURI(dev.device_uri) def findItemByURI(self, device_uri): index = 0 item = self.DeviceList.item(index) while item is not None: if item.device_uri == device_uri: return item index += 1 item = self.DeviceList.item(index) def findDeviceByURI(self, device_uri): try: return device_list[device_uri] except: return None def requestDeviceUpdate(self, dev=None, item=None): """ Submit device update request to update thread. """ if dev is None: dev = self.cur_device if dev is not None: dev.error_state = ERROR_STATE_REFRESHING self.updateDevice(dev, update_tab=False) self.sendMessage(dev.device_uri, '', EVENT_DEVICE_UPDATE_REQUESTED) def rescanDevices(self): """ Rescan and update all devices. """ if not self.updating: self.RefreshAllAction.setEnabled(False) try: self.refreshDeviceList() finally: self.RefreshAllAction.setEnabled(True) def callback(self): qApp.processEvents() # *********************************************************************************** # # DEVICE LIST RIGHT CLICK # # *********************************************************************************** def DeviceList_customContextMenuRequested(self, p): d = self.cur_device if d is not None: avail = d.device_state != DEVICE_STATE_NOT_FOUND and d.supported printer = d.device_type == DEVICE_TYPE_PRINTER and avail fax = d.fax_type > FAX_TYPE_NONE and prop.fax_build and d.device_type == DEVICE_TYPE_FAX and \ sys.hexversion >= 0x020300f0 and avail scan = d.scan_type > SCAN_TYPE_NONE and prop.scan_build and \ printer and self.user_settings.cmd_scan cpy = d.copy_type > COPY_TYPE_NONE and printer popup = QMenu(self) item = self.DeviceList.currentItem() if item is not None: if self.cur_device.error_state != ERROR_STATE_ERROR: if printer: popup.addAction(self.__tr("Print..."), lambda: self.contextMenuFunc(PrintDialog(self, self.cur_printer))) if scan: popup.addAction(self.__tr("Scan..."), lambda: self.contextMenuFunc(self.user_settings.cmd_scan)) #self.ScanButton_clicked) if cpy: popup.addAction(self.__tr("Make Copies..."), lambda: MakeCopiesDialog(self, self.cur_device_uri)) #self.MakeCopiesButton_clicked) else: # self.cur_device.device_type == DEVICE_TYPE_FAX: if fax: popup.addAction(self.__tr("Send Fax..."), lambda: self.contextMenuFunc(SendFaxDialog(self, self.cur_printer, self.cur_device_uri))) #self.SendFaxButton_clicked) popup.addSeparator() if not self.updating: popup.addAction(self.__tr("Refresh Device"), self.requestDeviceUpdate) #self.DeviceRefreshAction_activated) if not self.updating: popup.addAction(self.__tr("Refresh All"), self.rescanDevices) #self.RefreshAllAction_activated) popup.addSeparator() if self.DeviceList.viewMode() == QListView.IconMode: popup.addAction(self.__tr("View as List"), lambda: self.setDeviceListViewMode(QListView.ListMode)) else: popup.addAction(self.__tr("View as Icons"), lambda: self.setDeviceListViewMode(QListView.IconMode)) popup.exec_(self.DeviceList.mapToGlobal(p)) def contextMenuFunc(self, f): self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING) try: try: f.exec_() # Dialog except AttributeError: beginWaitCursor() if f.split(':')[0] in ('http', 'https', 'file'): log.debug("Opening browser to: %s" % item.cmd) utils.openURL(f) else: self.runExternalCommand(f) QTimer.singleShot(1000, self.unlockClick) finally: self.sendMessage('', '', EVENT_DEVICE_START_POLLING) # *********************************************************************************** # # PRINTER NAME COMBOS # # *********************************************************************************** def updatePrinterCombos(self): self.PrintSettingsPrinterNameCombo.clear() self.PrintControlPrinterNameCombo.clear() if self.cur_device is not None and \ self.cur_device.supported: self.cur_device.updateCUPSPrinters() for c in self.cur_device.cups_printers: self.PrintSettingsPrinterNameCombo.insertItem(0, c.decode("utf-8")) self.PrintControlPrinterNameCombo.insertItem(0, c.decode("utf-8")) self.cur_printer = unicode(self.PrintSettingsPrinterNameCombo.currentText()) def PrintSettingsPrinterNameCombo_activated(self, s): self.cur_printer = unicode(s) self.updateCurrentTab() def PrintControlPrinterNameCombo_activated(self, s): self.cur_printer = unicode(s) self.updateCurrentTab() # *********************************************************************************** # # FUNCTIONS/ACTION TAB # # *********************************************************************************** def initActionsTab(self): self.click_lock = None self.ActionsList.setIconSize(QSize(32, 32)) self.connect(self.ActionsList, SIGNAL("itemClicked(QListWidgetItem *)"), self.ActionsList_clicked) self.connect(self.ActionsList, SIGNAL("itemDoubleClicked(QListWidgetItem *)"), self.ActionsList_clicked) def updateActionsTab(self): beginWaitCursor() try: self.ActionsList.clear() d = self.cur_device if d is not None: avail = d.device_state != DEVICE_STATE_NOT_FOUND and d.supported fax = d.fax_type > FAX_TYPE_NONE and prop.fax_build and d.device_type == DEVICE_TYPE_FAX and \ sys.hexversion >= 0x020300f0 and avail printer = d.device_type == DEVICE_TYPE_PRINTER and avail scan = d.scan_type > SCAN_TYPE_NONE and prop.scan_build and \ printer and self.user_settings.cmd_scan cpy = d.copy_type > COPY_TYPE_NONE and printer req_plugin = d.plugin == PLUGIN_REQUIRED opt_plugin = d.plugin == PLUGIN_OPTIONAL try: back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \ device.parseDeviceURI(self.cur_device_uri) except Error: return hplip_conf = ConfigParser.ConfigParser() fp = open("/etc/hp/hplip.conf", "r") hplip_conf.readfp(fp) fp.close() try: plugin_installed = utils.to_bool(hplip_conf.get("hplip", "plugin")) except ConfigParser.NoOptionError: plugin_installed = False if d.plugin != PLUGIN_NONE: if req_plugin and plugin_installed: x = self.__tr("Download and installIs user added to %s group(s)" %utils.list_to_string(utils.addgroup()))) finally: endWaitCursor() def AcceptRejectButton_clicked(self): beginWaitCursor() try: if self.printer_accepting: result = cups.reject(self.cur_printer) if result: if self.cur_device.device_type == DEVICE_TYPE_PRINTER: e = EVENT_PRINTER_QUEUE_REJECTING_JOBS else: e = EVENT_FAX_QUEUE_REJECTING_JOBS else: result = cups.accept(self.cur_printer) if result: if self.cur_device.device_type == DEVICE_TYPE_PRINTER: e = EVENT_PRINTER_QUEUE_ACCEPTING_JOBS else: e = EVENT_FAX_QUEUE_ACCEPTING_JOBS if result: self.updatePrintController() self.cur_device.sendEvent(e, self.cur_printer) else: if os.geteuid!=0 and utils.addgroup()!=[]: FailureUI(self, self.__tr("Accept/Reject printer queue operation fails. Could not connect to CUPS Server
Is user added to %s group(s)" %utils.list_to_string(utils.addgroup()))) finally: endWaitCursor() def SetDefaultButton_clicked(self): beginWaitCursor() try: result = cups.setDefaultPrinter(self.cur_printer.encode('utf8')) if not result: if os.geteuid!=0 and utils.addgroup()!=[]: FailureUI(self, self.__tr("Set printer queue as default operation fails. Could not connect to CUPS Server
Is user added to %s group(s)" %utils.list_to_string(utils.addgroup()))) else: self.updatePrintController() if self.cur_device.device_type == DEVICE_TYPE_PRINTER: e = EVENT_PRINTER_QUEUE_SET_AS_DEFAULT else: e = EVENT_FAX_QUEUE_SET_AS_DEFAULT self.cur_device.sendEvent(e, self.cur_printer) finally: endWaitCursor() def cancelCheckedJobs(self): beginWaitCursor() try: item = self.JobTable.firstChild() while item is not None: if item.isOn(): self.cur_device.cancelJob(item.job_id) item = item.nextSibling() finally: endWaitCursor() self.updatePrintControlTab() # *********************************************************************************** # # EXIT/CHILD CLEANUP # # *********************************************************************************** def closeEvent(self, event): self.cleanup() event.accept() def cleanup(self): self.cleanupChildren() def cleanupChildren(self): log.debug("Cleaning up child processes.") try: os.waitpid(-1, os.WNOHANG) except OSError: pass def quit(self): self.cleanupChildren() self.close() # *********************************************************************************** # # DEVICE SETTINGS PLUGIN # # *********************************************************************************** # *********************************************************************************** # # SETTINGS DIALOG # # *********************************************************************************** def PreferencesAction_activated(self, tab_to_show=0): dlg = SettingsDialog(self) dlg.TabWidget.setCurrentIndex(tab_to_show) if dlg.exec_() == QDialog.Accepted: self.user_settings.load() if self.cur_device is not None: self.cur_device.sendEvent(EVENT_USER_CONFIGURATION_CHANGED, self.cur_printer) # *********************************************************************************** # # SETUP/REMOVE # # *********************************************************************************** def SetupDeviceAction_activated(self): if utils.which('hp-setup'): cmd = 'hp-setup --gui' else: cmd = 'python ./setup.py --gui' log.debug(cmd) utils.run(cmd, log_output=True, password_func=None, timeout=1) self.rescanDevices() self.updatePrinterCombos() def RemoveDeviceAction_activated(self): if utils.which('hp-setup'): cmd = 'hp-setup --gui --remove' else: cmd = 'python ./setup.py --gui --remove' if self.cur_device_uri is not None: cmd += ' --device=%s' % self.cur_device_uri log.debug(cmd) utils.run(cmd, log_output=True, password_func=None, timeout=1) self.rescanDevices() self.updatePrinterCombos() # *********************************************************************************** # # MISC # # *********************************************************************************** def runExternalCommand(self, cmd, macro_char='%'): beginWaitCursor() try: if len(cmd) == 0: FailureUI(self.__tr("
Unable to run command. No command specified.
Use
Configure...to specify a command to run.")) log.error("No command specified. Use settings to configure commands.") else: log.debug("Run: %s %s (%s) %s" % ("*"*20, cmd, self.cur_device_uri, "*"*20)) log.debug(cmd) try: cmd = ''.join([self.cur_device.device_vars.get(x, x) \ for x in cmd.split(macro_char)]) except AttributeError: pass log.debug(cmd) path = cmd.split()[0] args = cmd.split() log.debug(path) log.debug(args) self.cleanupChildren() os.spawnvp(os.P_NOWAIT, path, args) qApp.processEvents() finally: endWaitCursor() def helpContents(self): utils.openURL(self.docs) def helpAbout(self): dlg = AboutDialog(self, prop.version, self.toolbox_version + " (Qt4)") dlg.exec_() def __tr(self,s,c = None): return qApp.translate("DevMgr5",s,c) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX class PasswordDialog(QDialog): def __init__(self, prompt, parent=None, name=None, modal=0, fl=0): QDialog.__init__(self, parent) self.prompt = prompt Layout= QGridLayout(self) Layout.setMargin(11) Layout.setSpacing(6) self.PromptTextLabel = QLabel(self) Layout.addWidget(self.PromptTextLabel,0,0,1,3) self.UsernameTextLabel = QLabel(self) Layout.addWidget(self.UsernameTextLabel,1,0) self.UsernameLineEdit = QLineEdit(self) self.UsernameLineEdit.setEchoMode(QLineEdit.Normal) Layout.addWidget(self.UsernameLineEdit,1,1,1,2) self.PasswordTextLabel = QLabel(self) Layout.addWidget(self.PasswordTextLabel,2,0) self.PasswordLineEdit = QLineEdit(self) self.PasswordLineEdit.setEchoMode(QLineEdit.Password) Layout.addWidget(self.PasswordLineEdit,2,1,1,2) self.OkPushButton = QPushButton(self) Layout.addWidget(self.OkPushButton,3,2) self.languageChange() self.resize(QSize(420,163).expandedTo(self.minimumSizeHint())) self.connect(self.OkPushButton, SIGNAL("clicked()"), self.accept) self.connect(self.PasswordLineEdit, SIGNAL("returnPressed()"), self.accept) def getUsername(self): return unicode(self.UsernameLineEdit.text()) def getPassword(self): return unicode(self.PasswordLineEdit.text()) def languageChange(self): self.setWindowTitle(self.__tr("HP Device Manager - Enter Username/Password")) self.PromptTextLabel.setText(self.__tr(self.prompt)) self.UsernameTextLabel.setText(self.__tr("Username:")) self.PasswordTextLabel.setText(self.__tr("Password:")) self.OkPushButton.setText(self.__tr("OK")) def __tr(self,s,c = None): return qApp.translate("DevMgr5",s,c) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX def showPasswordUI(prompt): try: dlg = PasswordDialog(prompt, None) if dlg.exec_() == QDialog.Accepted: return (dlg.getUsername(), dlg.getPassword()) finally: pass return ("", "") def openEWS(host, zc): if zc: status, ip = hpmudext.get_zc_ip_address(zc) if status != hpmudext.HPMUD_R_OK: ip = "hplipopensource.com" else: ip = host return "http://%s" % ip