%PDF- %PDF-
| Direktori : /usr/share/hplip/ui5/ |
| Current File : //usr/share/hplip/ui5/setupdialog.py |
# -*- coding: utf-8 -*-
#
# (c) Copyright 2001-2015 HP Development Company, L.P.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Authors: Don Welch, Naga Samrat Chowdary Narla
#
# StdLib
import socket
import operator
import subprocess
import signal
# Local
from base.g import *
from base import device, utils, models, pkit
from prnt import cups
from base.codes import *
from .ui_utils import *
from installer import pluginhandler
from base.sixext import to_unicode, PY3, from_unicode_to_str
# Qt
try:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
except ImportError:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
# Ui
from .setupdialog_base import Ui_Dialog
from .plugindialog import PluginDialog
from .wifisetupdialog import WifiSetupDialog, SUCCESS_CONNECTED
# Fax
try:
from fax import fax
fax_import_ok = True
except ImportError:
# This can fail on Python < 2.3 due to the datetime module
fax_import_ok = False
log.warning("Fax setup disabled - Python 2.3+ required.")
PAGE_DISCOVERY = 0
PAGE_DEVICES = 1
PAGE_ADD_PRINTER = 2
PAGE_REMOVE = 3
BUTTON_NEXT = 0
BUTTON_FINISH = 1
BUTTON_ADD_PRINTER = 2
BUTTON_REMOVE = 3
ADVANCED_SHOW = 0
ADVANCED_HIDE = 1
DEVICE_DESC_ALL = 0
DEVICE_DESC_SINGLE_FUNC = 1
DEVICE_DESC_MULTI_FUNC = 2
class PasswordDialog(QDialog):
def __init__(self, prompt, parent=None, name=None, modal=0, fl=0):
QDialog.__init__(self, parent)
# Application icon
self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128')))
self.prompt = prompt
Layout = QGridLayout(self)
Layout.setContentsMargins(11, 11, 11, 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.CancelPushButton = QPushButton(self)
Layout.addWidget(self.CancelPushButton, 3, 1)
self.languageChange()
self.resize(QSize(420, 163).expandedTo(self.minimumSizeHint()))
self.OkPushButton.clicked.connect(self.accept)
self.CancelPushButton.clicked.connect(self.reject)
self.PasswordLineEdit.returnPressed.connect(self.accept)
def setDefaultUsername(self, defUser, allowUsernameEdit=True):
self.UsernameLineEdit.setText(defUser)
if not allowUsernameEdit:
self.UsernameLineEdit.setReadOnly(True)
self.UsernameLineEdit.setStyleSheet(
"QLineEdit {background-color: lightgray}")
def getUsername(self):
return to_unicode(self.UsernameLineEdit.text())
def getPassword(self):
return to_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"))
self.CancelPushButton.setText(self.__tr("Cancel"))
def __tr(self, s, c=None):
return qApp.translate("SetupDialog", s, c)
def FailureMessageUI(prompt):
try:
dlg = PasswordDialog(prompt, None)
FailureUI(dlg, prompt)
finally:
pass
def showPasswordUI(prompt, userName=None, allowUsernameEdit=True):
try:
dlg = PasswordDialog(prompt, None)
if userName != None:
dlg.setDefaultUsername(userName, allowUsernameEdit)
if dlg.exec_() == QDialog.Accepted:
return (dlg.getUsername(), dlg.getPassword())
finally:
pass
return ("", "")
class DeviceTableWidgetItem(QTableWidgetItem):
def __init__(self, text, device_uri):
QTableWidgetItem.__init__(self, text, QTableWidgetItem.UserType)
self.device_uri = device_uri
class SetupDialog(QDialog, Ui_Dialog):
def __init__(self, parent, param, jd_port, device_uri=None, remove=False):
QDialog.__init__(self, parent)
self.setupUi(self)
self.param = param
self.jd_port = jd_port
self.device_uri = device_uri
self.remove = remove
if device_uri:
log.info("Using device: %s" % device_uri)
self.initUi()
if self.remove:
QTimer.singleShot(0, self.showRemovePage)
else:
if self.skip_discovery:
self.discovery_method = 0 # mDNS
QTimer.singleShot(0, self.showDevicesPage)
else:
QTimer.singleShot(0, self.showDiscoveryPage)
cups.setPasswordCallback(showPasswordUI)
#
# INIT
#
def initUi(self):
self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128')))
# connect signals/slots
self.CancelButton.clicked.connect(self.CancelButton_clicked)
self.BackButton.clicked.connect(self.BackButton_clicked)
self.NextButton.clicked.connect(self.NextButton_clicked)
self.ManualGroupBox.clicked.connect(self.ManualGroupBox_clicked)
signal.signal(signal.SIGINT, signal.SIG_DFL)
self.faxnumberChanged = False
self.faxCompanyNameChanged = False
if self.remove:
self.initRemovePage()
self.max_page = 1
else:
self.initDiscoveryPage()
self.initDevicesPage()
self.initAddPrinterPage()
self.max_page = PAGE_ADD_PRINTER
#
# DISCOVERY PAGE
#
def initDiscoveryPage(self):
self.UsbRadioButton.setChecked(True)
self.setUsbRadioButton(True)
self.ManualGroupBox.setChecked(False)
self.advanced = False
self.manual = False
self.skip_discovery = False
self.discovery_method = 0
self.NetworkRadioButton.setEnabled(prop.net_build)
self.WirelessButton.setEnabled(prop.net_build)
self.ParallelRadioButton.setEnabled(prop.par_build)
self.devices = {}
self.bus = 'usb'
self.timeout = 5
self.ttl = 4
self.search = ''
self.print_test_page = False
self.device_desc = DEVICE_DESC_ALL
if self.param:
log.info("Searching for device...")
self.manual = True
self.advanced = True
self.ManualParamLineEdit.setText(self.param)
self.JetDirectSpinBox.setValue(self.jd_port)
self.ManualGroupBox.setChecked(True)
self.DiscoveryOptionsGroupBox.setEnabled(False)
if self.manualDiscovery():
self.skip_discovery = True
else:
FailureUI(self, self.__tr(
"<b>Device not found.</b> <p>Please make sure your printer is properly connected and powered-on."))
match = device.usb_pat.match(self.param)
if match is not None:
self.UsbRadioButton.setChecked(True)
self.setUsbRadioButton(True)
else:
match = device.dev_pat.match(self.param)
if match is not None and prop.par_build:
self.ParallelRadioButton.setChecked(True)
self.setParallelRadioButton(True)
else:
match = device.ip_pat.match(self.param)
if match is not None and prop.net_build:
self.NetworkRadioButton.setChecked(True)
self.setNetworkRadioButton(True)
else:
FailureUI(self, self.__tr(
"<b>Invalid manual discovery parameter.</b>"))
elif self.device_uri: # If device URI specified on the command line, skip discovery
# if the device URI is well-formed (but not necessarily valid)
try:
back_end, is_hp, self.bus, model, serial, dev_file, host, zc, port = \
device.parseDeviceURI(self.device_uri)
except Error:
log.error("Invalid device URI specified: %s" % self.device_uri)
else:
name = host
if self.bus == 'net':
try:
log.debug("Trying to get hostname for device...")
name = socket.gethostbyaddr(host)[0]
except socket.herror:
log.debug("Failed.")
else:
log.debug("Host name=%s" % name)
self.devices = {self.device_uri: (model, model, name)}
self.skip_discovery = True
# If no network or parallel, usb is only option, skip initial page...
elif not prop.par_build and not prop.net_build:
self.skip_discovery = True
self.bus = 'usb'
self.UsbRadioButton.setChecked(True)
self.setUsbRadioButton(True)
if prop.fax_build and prop.scan_build:
self.DeviceTypeComboBox.addItem(
"All devices/printers", DEVICE_DESC_ALL)
self.DeviceTypeComboBox.addItem(
"Single function printers only", DEVICE_DESC_SINGLE_FUNC)
self.DeviceTypeComboBox.addItem(
"All-in-one/MFP devices only", DEVICE_DESC_MULTI_FUNC)
else:
self.DeviceTypeComboBox.setEnabled(False)
self.AdvancedButton.clicked.connect(self.AdvancedButton_clicked)
self.UsbRadioButton.toggled.connect(self.UsbRadioButton_toggled)
self.NetworkRadioButton.toggled.connect(
self.NetworkRadioButton_toggled)
self.WirelessButton.toggled.connect(self.WirelessButton_toggled)
self.ParallelRadioButton.toggled.connect(
self.ParallelRadioButton_toggled)
self.NetworkTTLSpinBox.valueChanged.connect(
self.NetworkTTLSpinBox_valueChanged)
self.NetworkTimeoutSpinBox.valueChanged.connect(
self.NetworkTimeoutSpinBox_valueChanged)
self.ManualGroupBox.toggled.connect(self.ManualGroupBox_toggled)
self.showAdvanced()
def ManualGroupBox_toggled(self, checked):
self.DiscoveryOptionsGroupBox.setEnabled(not checked)
def manualDiscovery(self):
# Validate param...
device_uri, sane_uri, fax_uri = device.makeURI(
self.param, self.jd_port)
if device_uri:
log.info("Found device: %s" % device_uri)
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
device.parseDeviceURI(device_uri)
name = host
if bus == 'net':
try:
if device.ip_pat.search(name) is not None:
log.debug(
"Getting host name from IP address (%s)" % name)
name = socket.gethostbyaddr(host)[0]
except (socket.herror, socket.gaierror):
pass
self.devices = {device_uri: (model, model, name)}
if bus == 'usb':
self.UsbRadioButton.setChecked(True)
self.setUsbRadioButton(True)
elif bus == 'net' and prop.net_build:
self.NetworkRadioButton.setChecked(True)
self.setNetworkRadioButton(True)
elif bus == 'par' and prop.par_build:
self.ParallelRadioButton.setChecked(True)
self.setParallelRadioButton(True)
return True
return False
def ManualGroupBox_clicked(self, checked):
self.manual = checked
network = self.NetworkRadioButton.isChecked()
self.setJetDirect(network)
def showDiscoveryPage(self):
self.BackButton.setEnabled(False)
self.NextButton.setEnabled(True)
self.setNextButton(BUTTON_NEXT)
self.displayPage(PAGE_DISCOVERY)
def AdvancedButton_clicked(self):
self.advanced = not self.advanced
self.showAdvanced()
def showAdvanced(self):
if self.advanced:
self.AdvancedStackedWidget.setCurrentIndex(ADVANCED_SHOW)
self.AdvancedButton.setText(self.__tr("Hide Advanced Options"))
self.AdvancedButton.setIcon(QIcon(load_pixmap("minus", "16x16")))
else:
self.AdvancedStackedWidget.setCurrentIndex(ADVANCED_HIDE)
self.AdvancedButton.setText(self.__tr("Show Advanced Options"))
self.AdvancedButton.setIcon(QIcon(load_pixmap("plus", "16x16")))
def setJetDirect(self, enabled):
self.JetDirectLabel.setEnabled(enabled and self.manual)
self.JetDirectSpinBox.setEnabled(enabled and self.manual)
def setNetworkOptions(self, enabled):
self.NetworkTimeoutLabel.setEnabled(enabled)
self.NetworkTimeoutSpinBox.setEnabled(enabled)
self.NetworkTTLLabel.setEnabled(enabled)
self.NetworkTTLSpinBox.setEnabled(enabled)
def setSearchOptions(self, enabled):
self.SearchLineEdit.setEnabled(enabled)
self.DeviceTypeComboBox.setEnabled(enabled)
self.DeviceTypeLabel.setEnabled(enabled)
def setManualDiscovery(self, enabled):
self.ManualGroupBox.setEnabled(enabled)
def setNetworkDiscovery(self, enabled):
self.NetworkDiscoveryMethodLabel.setEnabled(enabled)
self.NetworkDiscoveryMethodComboBox.setEnabled(enabled)
self.NetworkDiscoveryMethodComboBox.setCurrentIndex(0)
def UsbRadioButton_toggled(self, radio_enabled):
self.setUsbRadioButton(radio_enabled)
def setUsbRadioButton(self, checked):
self.setNetworkDiscovery(not checked)
self.setJetDirect(not checked)
self.setNetworkOptions(not checked)
self.setSearchOptions(checked)
self.setManualDiscovery(checked)
if checked:
self.ManualParamLabel.setText(
self.__tr("USB bus ID:device ID (bbb:ddd):"))
self.bus = 'usb'
# TODO: Set bbb:ddd validator
def NetworkRadioButton_toggled(self, radio_enabled):
self.setNetworkRadioButton(radio_enabled)
def setNetworkRadioButton(self, checked):
self.setNetworkDiscovery(checked)
self.setJetDirect(checked)
self.setNetworkOptions(checked)
self.setSearchOptions(checked)
self.setManualDiscovery(checked)
if checked:
self.ManualParamLabel.setText(
self.__tr("IP Address or network name:"))
self.bus = 'net'
# TODO: Reset validator
def WirelessButton_toggled(self, radio_enabled):
self.setWirelessButton(radio_enabled)
def setWirelessButton(self, checked):
self.setNetworkDiscovery(not checked)
self.setJetDirect(not checked)
self.setNetworkOptions(not checked)
self.setSearchOptions(not checked)
self.setManualDiscovery(not checked)
if checked:
self.ManualParamLabel.setText(
self.__tr("IP Address or network name:"))
self.bus = 'net'
def ParallelRadioButton_toggled(self, radio_enabled):
self.setParallelRadioButton(radio_enabled)
def setParallelRadioButton(self, checked):
self.setNetworkDiscovery(not checked)
self.setJetDirect(not checked)
self.setNetworkOptions(not checked)
self.setSearchOptions(not checked)
self.setManualDiscovery(not checked)
if checked:
self.ManualParamLabel.setText(self.__tr("Device node (/dev/...):"))
self.bus = 'par'
# TODO: Set /dev/... validator
def NetworkTTLSpinBox_valueChanged(self, ttl):
self.ttl = ttl
def NetworkTimeoutSpinBox_valueChanged(self, timeout):
self.timeout = timeout
#
# DEVICES PAGE
#
def initDevicesPage(self):
self.RefreshButton.clicked.connect(self.RefreshButton_clicked)
def showDevicesPage(self):
self.BackButton.setEnabled(True)
self.setNextButton(BUTTON_NEXT)
search = ""
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
if not self.devices:
if self.manual and self.param: # manual, but not passed-in on command line
self.manualDiscovery()
else: # probe
net_search_type = ''
if self.bus == 'net':
if self.discovery_method == 0:
net_search_type = "mdns"
elif self.discovery_method == 1:
net_search_type = "slp"
else:
net_search_type = "avahi"
log.info("Searching... (bus=%s, timeout=%d, ttl=%d, search=%s desc=%d, method=%s)" %
(self.bus, self.timeout, self.ttl, self.search or "(None)",
self.device_desc, net_search_type))
else:
log.info("Searching... (bus=%s, search=%s, desc=%d)" %
(self.bus, self.search or "(None)", self.device_desc))
if self.device_desc == DEVICE_DESC_SINGLE_FUNC:
filter_dict = {
'scan-type': (operator.le, SCAN_TYPE_NONE)}
elif self.device_desc == DEVICE_DESC_MULTI_FUNC:
filter_dict = {
'scan-type': (operator.gt, SCAN_TYPE_NONE)}
else: # DEVICE_DESC_ALL
filter_dict = {}
if self.bus == 'usb':
try:
from base import smart_install
except ImportError:
log.error(
"Failed to Import smart_install.py from base")
else: # if no Smart Install device found, ignores.
QApplication.restoreOverrideCursor()
smart_install.disable(GUI_MODE, 'qt4')
QApplication.setOverrideCursor(
QCursor(Qt.WaitCursor))
self.devices = device.probeDevices([self.bus], self.timeout, self.ttl,
filter_dict, self.search, net_search=net_search_type)
finally:
QApplication.restoreOverrideCursor()
self.clearDevicesTable()
if self.devices:
self.NextButton.setEnabled(True)
self.DevicesFoundIcon.setPixmap(load_pixmap('info', '16x16'))
if len(self.devices) == 1:
self.DevicesFoundLabel.setText(
self.__tr("<b>1 device found.</b> Click <i>Next</i> to continue."))
else:
self.DevicesFoundLabel.setText(self.__tr(
"<b>%s devices found.</b> Select the device to install and click <i>Next</i> to continue." % (len(self.devices))))
self.loadDevicesTable()
else:
self.NextButton.setEnabled(False)
self.DevicesFoundIcon.setPixmap(load_pixmap('error', '16x16'))
log.error("No devices found on bus: %s" % self.bus)
self.DevicesFoundLabel.setText(self.__tr(
"<b>No devices found.</b><br>Click <i>Back</i> to change discovery options, or <i>Refresh</i> to search again."))
if self.bus == 'net' and utils.check_lan():
FailureUI(self, self.__tr('''<b>HPLIP cannot detect printers in your network.</b><p>This may be due to existing firewall settings blocking the required ports.
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.
<b>https://developers.hp.com/hp-linux-imaging-and-printing/KnowledgeBase/Troubleshooting/TroubleshootNetwork</b></p>'''),
self.__tr("HP Device Manager"))
self.displayPage(PAGE_DEVICES)
def loadDevicesTable(self):
self.DevicesTableWidget.setRowCount(len(self.devices))
if self.bus == 'net':
headers = [self.__tr('Model'), self.__tr('IP Address'), self.__tr('Host Name'), self.__tr('Device URI')]
device_uri_col = 3
else:
headers = [self.__tr('Model'), self.__tr('Device URI')]
device_uri_col = 1
self.DevicesTableWidget.setColumnCount(len(headers))
self.DevicesTableWidget.setHorizontalHeaderLabels(headers)
flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled
for row, d in enumerate(self.devices):
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(d)
model_ui = models.normalizeModelUIName(model)
i = DeviceTableWidgetItem(str(model_ui), d)
i.setFlags(flags)
self.DevicesTableWidget.setItem(row, 0, i)
i = QTableWidgetItem(str(d))
i.setFlags(flags)
self.DevicesTableWidget.setItem(row, device_uri_col, i)
if self.bus == 'net':
i = QTableWidgetItem(str(host))
i.setFlags(flags)
self.DevicesTableWidget.setItem(row, 1, i)
i = QTableWidgetItem(str(self.devices[d][2]))
i.setFlags(flags)
self.DevicesTableWidget.setItem(row, 2, i)
self.DevicesTableWidget.resizeColumnsToContents()
self.DevicesTableWidget.selectRow(0)
self.DevicesTableWidget.setSortingEnabled(True)
self.DevicesTableWidget.sortItems(0)
def clearDevicesTable(self):
self.DevicesTableWidget.clear()
self.DevicesTableWidget.setRowCount(0)
self.DevicesTableWidget.setColumnCount(0)
def RefreshButton_clicked(self):
self.clearDevicesTable()
self.devices = []
QTimer.singleShot(0, self.showDevicesPage)
#
# ADD PRINTER PAGE
#
def initAddPrinterPage(self):
self.mq = {}
self.PrinterNameLineEdit.textEdited.connect(
self.PrinterNameLineEdit_textEdited)
self.FaxNameLineEdit.textEdited.connect(
self.FaxNameLineEdit_textEdited)
self.SetupPrintGroupBox.clicked.connect(
self.SetupPrintGroupBox_clicked)
self.SetupFaxGroupBox.clicked.connect(self.SetupFaxGroupBox_clicked)
self.PrinterNameLineEdit.setValidator(
PrinterNameValidator(self.PrinterNameLineEdit))
self.FaxNameLineEdit.setValidator(
PrinterNameValidator(self.FaxNameLineEdit))
self.FaxNumberLineEdit.setValidator(
PhoneNumValidator(self.FaxNumberLineEdit))
self.OtherPPDButton.setIcon(QIcon(load_pixmap('folder_open', '16x16')))
self.OtherPPDButton.clicked.connect(self.OtherPPDButton_clicked)
self.OtherPPDButton.setToolTip(
self.__tr("Browse for an alternative PPD file for this printer."))
self.printer_fax_names_same = False
self.printer_name = ''
self.fax_name = ''
self.fax_setup_ok = True
self.fax_setup = False
self.print_setup = False
def showAddPrinterPage(self):
# Install the plugin if needed...
pluginObj = pluginhandler.PluginHandle()
plugin = self.mq.get('plugin', PLUGIN_NONE)
plugin_reason = self.mq.get('plugin-reason', PLUGIN_REASON_NONE)
if plugin > PLUGIN_NONE:
if pluginObj.getStatus() != pluginhandler.PLUGIN_INSTALLED:
ok, sudo_ok = pkit.run_plugin_command(
plugin == PLUGIN_REQUIRED, plugin_reason)
if not sudo_ok:
FailureUI(self, self.__tr(
"<b>Unable to find an appropriate su/sudo utiltity to run hp-plugin.</b><p>Install kdesu, gnomesu, or gksu.</p>"))
return
if not ok or pluginObj.getStatus() != pluginhandler.PLUGIN_INSTALLED:
if plugin == PLUGIN_REQUIRED:
FailureUI(self, self.__tr("<b>The device you are trying to setup requires a binary plug-in. Some functionalities may not work as expected without plug-ins.<p> Please run 'hp-plugin' as normal user to install plug-ins.</b></p><p>Visit <u>http://hplipopensource.com</u> for more infomation.</p>"))
return
else:
WarningUI(self, self.__tr(
"Either you have chosen to skip the installation of the optional plug-in or that installation has failed. Your printer may not function at optimal performance."))
self.setNextButton(BUTTON_ADD_PRINTER)
self.print_setup = self.setDefaultPrinterName()
if self.print_setup:
self.SetupPrintGroupBox.setCheckable(True)
self.SetupPrintGroupBox.setEnabled(True)
self.SendTestPageCheckBox.setCheckable(True)
self.SendTestPageCheckBox.setEnabled(True)
self.findPrinterPPD()
self.updatePPD()
else:
self.print_ppd = None
self.SetupPrintGroupBox.setCheckable(False)
self.SetupPrintGroupBox.setEnabled(False)
self.SendTestPageCheckBox.setCheckable(False)
self.SendTestPageCheckBox.setEnabled(False)
if fax_import_ok and prop.fax_build and \
self.mq.get('fax-type', FAX_TYPE_NONE) not in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED):
self.fax_setup = True
self.SetupFaxGroupBox.setChecked(True)
self.SetupFaxGroupBox.setEnabled(True)
self.fax_setup = self.setDefaultFaxName()
if self.fax_setup:
self.findFaxPPD()
self.readwriteFaxInformation()
else:
self.fax_setup = False
self.SetupFaxGroupBox.setChecked(False)
self.SetupFaxGroupBox.setEnabled(False)
else:
self.SetupFaxGroupBox.setChecked(False)
self.SetupFaxGroupBox.setEnabled(False)
self.fax_name = ''
self.fax_name_ok = True
self.fax_setup = False
self.fax_setup_ok = True
if self.print_setup or self.fax_setup:
self.setAddPrinterButton()
self.displayPage(PAGE_ADD_PRINTER)
else:
log.info("Exiting the setup...")
self.close()
def updatePPD(self):
if self.print_ppd is None:
log.error("No appropriate print PPD file found for model %s" % self.model)
self.PPDFileLineEdit.setText(self.__tr('(Not found. Click browse button to select a PPD file.)'))
try:
self.PPDFileLineEdit.setStyleSheet("background-color: yellow")
except AttributeError:
pass
self.PrinterDescriptionLineEdit.setText(str(""))
else:
self.PPDFileLineEdit.setText(self.print_ppd[0])
self.PrinterDescriptionLineEdit.setText("")
try:
self.PPDFileLineEdit.setStyleSheet("")
except AttributeError:
pass
def OtherPPDButton_clicked(self, b):
ppd_file = to_unicode(QFileDialog.getOpenFileName(self, self.__tr("Select PPD File"),
sys_conf.get(
'dirs', 'ppd'),
self.__tr("PPD Files (*.ppd *.ppd.gz);;All Files (*)")))
if ppd_file and os.path.exists(ppd_file):
self.print_ppd = (ppd_file, cups.getPPDDescription(ppd_file))
self.updatePPD()
self.setAddPrinterButton()
def findPrinterPPD(self):
"""
for ubuntu 20.10 not able get ppd list from cups server.
so fetching ppds hplip ppds directly
"""
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
self.ppds = cups.getSystemPPDs()
self.ppd_name = ""
# if ppd list from cups server is empty searching for hplip ppds.
if not self.ppds:
ppdName = cups.getPpdName(self.model)
self.path = cups.getPPDPath1()
# path for hplip ppds in local system
self.ppd_name = str(self.path + '/' + ppdName)
self.print_ppd = (self.ppd_name, '')
else:
self.print_ppd = cups.getPPDFile2(
self.mq, self.model, self.ppds)
if "scanjet" in self.model or "digital_sender" in self.model:
self.print_ppd = None
finally:
QApplication.restoreOverrideCursor()
def findFaxPPD(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
self.fax_ppd, fax_ppd_name, nick = cups.getFaxPPDFile(
self.mq, self.model)
if self.fax_ppd:
self.fax_setup_ok = True
else:
self.fax_setup_ok = False
FailureUI(self, self.__tr(
"<b>Unable to locate the HPLIP Fax PPD file:</b><p>%s.ppd.gz</p><p>Fax setup has been disabled." % fax_ppd_name))
self.fax_setup = False
self.SetupFaxGroupBox.setChecked(False)
self.SetupFaxGroupBox.setEnabled(False)
finally:
QApplication.restoreOverrideCursor()
def setDefaultPrinterName(self):
self.installed_print_devices = device.getSupportedCUPSDevices(['hp'])
log.debug(self.installed_print_devices)
self.installed_queues = [p.name for p in cups.getPrinters()]
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(
self.device_uri)
default_model = utils.xstrip(model.replace(
'series', '').replace('Series', ''), '_')
printer_name = default_model
installed_printer_names = device.getSupportedCUPSPrinterNames(['hp'])
# Check for duplicate names
if (self.device_uri in self.installed_print_devices and printer_name in self.installed_print_devices[self.device_uri]) \
or (printer_name in installed_printer_names):
warn_text = self.__tr("<b>One or more print queues already exist for this device: %s</b>.<br> <b>Would you like to install another print queue for this device ?</b>" %
', '.join([printer for printer in installed_printer_names if printer_name in printer]))
if (QMessageBox.warning(self,
self.windowTitle(),
warn_text,
QMessageBox.Yes |
QMessageBox.No,
QMessageBox.NoButton) == QMessageBox.Yes):
i = 2
while True:
t = printer_name + "_%d" % i
if (t not in installed_printer_names) and (self.device_uri not in self.installed_print_devices or t not in self.installed_print_devices[self.device_uri]):
printer_name += "_%d" % i
break
i += 1
else:
self.printer_name_ok = False
return False
self.printer_name_ok = True
self.PrinterNameLineEdit.setText(printer_name)
log.debug(printer_name)
self.printer_name = printer_name
return True
def setDefaultFaxName(self):
self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
log.debug(self.installed_fax_devices)
self.fax_uri = self.device_uri.replace('hp:', 'hpfax:')
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(
self.fax_uri)
default_model = utils.xstrip(model.replace(
'series', '').replace('Series', ''), '_')
fax_name = default_model + "_fax"
installed_fax_names = device.getSupportedCUPSPrinterNames(['hpfax'])
# Check for duplicate names
if (self.fax_uri in self.installed_fax_devices and fax_name in self.installed_fax_devices[self.fax_uri]) \
or (fax_name in installed_fax_names):
warn_text = self.__tr(
"<b>One or more fax queues already exist for this device: %s</b>.<br> <b>Would you like to install another fax queue for this device ?</b>" %
', '.join([fax_device for fax_device in installed_fax_names if fax_name in fax_device]))
if (QMessageBox.warning(self,
self.windowTitle(),
warn_text,
QMessageBox.Yes |
QMessageBox.No,
QMessageBox.NoButton) == QMessageBox.Yes):
i = 2
while True:
t = fax_name + "_%d" % i
if (t not in installed_fax_names) and (self.fax_uri not in self.installed_fax_devices or t not in self.installed_fax_devices[self.fax_uri]):
fax_name += "_%d" % i
break
i += 1
else:
self.fax_name_ok = False
return False
self.fax_name_ok = True
self.FaxNameLineEdit.setText(fax_name)
self.fax_name = fax_name
return True
def PrinterNameLineEdit_textEdited(self, t):
self.printer_name = to_unicode(t)
self.printer_name_ok = True
if not self.printer_name:
self.PrinterNameLineEdit.setToolTip(
self.__tr('You must enter a name for the printer.'))
self.printer_name_ok = False
elif self.fax_name == self.printer_name:
s = self.__tr(
'The printer name and fax name must be different. Please choose different names.')
self.PrinterNameLineEdit.setToolTip(s)
self.FaxNameLineEdit.setToolTip(s)
self.fax_name_ok = False
self.printer_name_ok = False
self.printer_fax_names_same = True
elif self.printer_name in self.installed_queues:
self.PrinterNameLineEdit.setToolTip(self.__tr(
'A printer already exists with this name. Please choose a different name.'))
self.printer_name_ok = False
elif self.printer_fax_names_same:
if self.fax_name != self.printer_name:
self.printer_fax_names_same = False
self.printer_name_ok = True
self.FaxNameLineEdit.emit(SIGNAL("textEdited(const QString &)"),
self.FaxNameLineEdit.text())
self.setIndicators()
self.setAddPrinterButton()
def FaxNameLineEdit_textEdited(self, t):
self.fax_name = to_unicode(t)
self.fax_name_ok = True
if not self.fax_name:
self.FaxNameLineEdit.setToolTip(
self.__tr('You must enter a fax name.'))
self.fax_name_ok = False
elif self.fax_name == self.printer_name:
s = self.__tr(
'The printer name and fax name must be different. Please choose different names.')
self.PrinterNameLineEdit.setToolTip(s)
self.FaxNameLineEdit.setToolTip(s)
self.printer_name_ok = False
self.fax_name_ok = False
self.printer_fax_names_same = True
elif self.fax_name in self.installed_queues:
self.FaxNameLineEdit.setToolTip(self.__tr(
'A fax already exists with this name. Please choose a different name.'))
self.fax_name_ok = False
elif self.printer_fax_names_same:
if self.fax_name != self.printer_name:
self.printer_fax_names_same = False
self.fax_name_ok = True
self.PrinterNameLineEdit.emit(SIGNAL("textEdited(const QString&)"),
self.PrinterNameLineEdit.text())
self.setIndicators()
self.setAddPrinterButton()
def SetupPrintGroupBox_clicked(self):
if not self.SetupPrintGroupBox.isChecked():
self.SendTestPageCheckBox.setCheckable(False)
self.SendTestPageCheckBox.setEnabled(False)
else:
self.SendTestPageCheckBox.setCheckable(True)
self.SendTestPageCheckBox.setEnabled(True)
self.setAddPrinterButton()
def SetupFaxGroupBox_clicked(self):
self.setAddPrinterButton()
def setIndicators(self):
if self.printer_name_ok:
self.PrinterNameLineEdit.setToolTip(str(""))
try:
self.PrinterNameLineEdit.setStyleSheet("")
except AttributeError:
pass
else:
try:
self.PrinterNameLineEdit.setStyleSheet(
"background-color: yellow")
except AttributeError:
pass
if self.fax_name_ok:
self.FaxNameLineEdit.setToolTip(str(""))
try:
self.PrinterNameLineEdit.setStyleSheet("")
except AttributeError:
pass
else:
try:
self.PrinterNameLineEdit.setStyleSheet(
"background-color: yellow")
except AttributeError:
pass
def setAddPrinterButton(self):
'''
If the device is on usb and os doesn't supports ipp-usb we assign new ipp uri to the printer.
this is for driverless usb printer held by ippusbxd service on ubuntu 20 and above.
For network devices follow the old code.
'''
if(self.bus == "usb" and not os.path.isdir('/usr/share/ipp-usb/quirks')):
from base import local
from base.local import detectLocalDevices
try:
detected_devices = local.detectLocalDevices(ttl=4, timeout=10)
log.debug(" Detected devices from local.py ")
log.debug(detected_devices)
current_printer = self.model.replace('_', " ")
log.debug(" current pritner is: ")
# log.debug(detected_devices['printer_uri'])
log.debug(current_printer)
for key in detected_devices:
if(detected_devices[key].lower() == current_printer.lower()):
log.debug("Assign ipp URI to the current printer")
# self.device_uri = Ipp_uri
self.device_uri = detected_devices['printer_uri']
else:
return
except Error as socket_error:
socket.error = socket_error
log.error(
"An error occured during network probe.[%s]" % socket_error)
raise ERROR_INTERNAL
if self.SetupPrintGroupBox.isChecked() or self.SetupFaxGroupBox.isChecked():
self.NextButton.setEnabled((self.print_setup and self.printer_name_ok and self.print_ppd is not None) or
(self.fax_setup and self.fax_name_ok))
else:
self.NextButton.setEnabled(False)
#
# ADD PRINTER
#
def addPrinter(self):
if self.print_setup:
print_sts = self.setupPrinter()
if print_sts == cups.IPP_FORBIDDEN or print_sts == cups.IPP_NOT_AUTHENTICATED or print_sts == cups.IPP_NOT_AUTHORIZED:
pass # User doesn't have sufficient permissions so ignored.
if print_sts == cups.IPP_OK:
self.flashFirmware()
if self.print_test_page:
self.printTestPage()
if self.fax_setup:
if self.setupFax() == cups.IPP_OK:
if self.FaxNumberLineEdit.text() != self.fax_number:
self.faxnumberChanged = True
if self.NameCompanyLineEdit.text() != self.fax_name_company:
self.faxCompanyNameChanged = True
if self.faxnumberChanged or self.faxCompanyNameChanged:
self.fax_name_company = to_unicode(
self.NameCompanyLineEdit.text())
self.fax_number = to_unicode(self.FaxNumberLineEdit.text())
self.readwriteFaxInformation(False)
self.close()
#
# Updating firmware download for supported devices.
#
def flashFirmware(self):
if self.mq.get('fw-download', False):
try:
d = device.Device(self.device_uri)
except Error as e:
FailureUI(self, self.__tr(
"<b>Error opening device. Firmware download is Failed.</b><p>%s (%s)." % (e.msg, e.opt)))
else:
if d.downloadFirmware():
log.info("Firmware download successful.\n")
else:
FailureUI(self, self.__tr(
"<b>Firmware download is Failed.</b>"))
d.close()
#
# SETUP PRINTER/FAX
#
def setupPrinter(self):
status = cups.IPP_BAD_REQUEST
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
# assume foomatic: or some such
if not os.path.exists(self.print_ppd[0]):
add_prnt_args = (from_unicode_to_str(self.printer_name), self.device_uri,
self.print_location, '', self.print_ppd[0], self.print_desc)
else:
add_prnt_args = (from_unicode_to_str(self.printer_name), self.device_uri,
self.print_location, self.print_ppd[0], '', self.print_desc)
status, status_str = cups.cups_operation(
cups.addPrinter, GUI_MODE, 'qt4', self, *add_prnt_args)
log.debug(device.getSupportedCUPSDevices(['hp']))
if status != cups.IPP_OK:
QApplication.restoreOverrideCursor()
FailureUI(self, self.__tr(
"<b>Printer queue setup failed.</b> <p>Error : %s" % status_str))
else:
# sending Event to add this device in hp-systray
utils.sendEvent(EVENT_CUPS_QUEUES_ADDED,
self.device_uri, self.printer_name)
finally:
QApplication.restoreOverrideCursor()
return status
def setupFax(self):
status = cups.IPP_BAD_REQUEST
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
if not os.path.exists(self.fax_ppd):
status, status_str = cups.addPrinter(self.fax_name,
self.fax_uri, self.fax_location, '', self.fax_ppd, self.fax_desc)
else:
status, status_str = cups.addPrinter(self.fax_name,
self.fax_uri, self.fax_location, self.fax_ppd, '', self.fax_desc)
log.debug(device.getSupportedCUPSDevices(['hpfax']))
if status != cups.IPP_OK:
QApplication.restoreOverrideCursor()
FailureUI(self, self.__tr(
"<b>Fax queue setup failed.</b><p>Error : %s" % status_str))
else:
# sending Event to add this device in hp-systray
utils.sendEvent(EVENT_CUPS_QUEUES_ADDED,
self.fax_uri, self.fax_name)
finally:
QApplication.restoreOverrideCursor()
return status
def readwriteFaxInformation(self, read=True):
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
d = fax.getFaxDevice(self.fax_uri, disable_dbus=True)
while True:
try:
d.open()
except Error:
error_text = self.__tr(
"Unable to communicate with the device. Please check the device and try again.")
log.error(to_unicode(error_text))
if QMessageBox.critical(self,
self.windowTitle(),
error_text,
QMessageBox.Retry | QMessageBox.Default |\
QMessageBox.Cancel | QMessageBox.Escape,
QMessageBox.NoButton) == QMessageBox.Cancel:
break
else:
try:
tries = 0
ok = True
while True:
tries += 1
try:
if read:
# self.fax_number = str(d.getPhoneNum())
# self.fax_name_company = str(d.getStationName())
try:
self.fax_number = to_unicode(d.getPhoneNum())
self.fax_name_company = to_unicode(d.getStationName())
except:
log.debug("IO Error")
self.fax_number = ""
self.fax_name_company = ""
else:
if d.isAuthRequired() == True:
promptText = "Enter the printer's username password password\n"
while(True):
username, password = showPasswordUI(
promptText)
if username == '' or password == '':
return
respCode = d.getCDMToken(
username, password)
if respCode != 200:
promptText = "Invalid Username or Password!.\nRernter the printer's username password password\n"
continue
break
if self.faxCompanyNameChanged:
d.setStationName(self.fax_name_company)
if self.faxnumberChanged:
d.setPhoneNum(self.fax_number)
except Error:
error_text = self.__tr(
"<b>Device I/O Error</b><p>Could not communicate with device. Device may be busy.")
log.error(to_unicode(error_text))
if QMessageBox.critical(self,
self.windowTitle(),
error_text,
QMessageBox.Retry | QMessageBox.Default |\
QMessageBox.Cancel | QMessageBox.Escape,
QMessageBox.NoButton) == QMessageBox.Cancel:
break
time.sleep(5)
ok = False
if tries > 12:
break
else:
ok = True
break
finally:
d.close()
if ok and read:
self.FaxNumberLineEdit.setText(self.fax_number)
self.NameCompanyLineEdit.setText(self.fax_name_company)
break
finally:
QApplication.restoreOverrideCursor()
def printTestPage(self):
try:
d = device.Device(self.device_uri)
except Error as e:
FailureUI(self, self.__tr(
"<b>Device error:</b><p>%s (%s)." % (e.msg, e.opt)))
else:
try:
d.open()
except Error:
FailureUI(self, self.__tr(
"<b>Unable to print to printer.</b><p>Please check device and try again."))
else:
if d.isIdleAndNoError():
d.close()
try:
d.printTestPage(self.printer_name)
except Error as e:
if e.opt == ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE:
FailureUI(self, self.__tr(
"<b>No CUPS queue found for device.</b><p>Please install the printer in CUPS and try again."))
else:
FailureUI(self, self.__tr(
"<b>Printer Error</b><p>An error occured: %s (code=%d)." % (e.msg, e.opt)))
else:
FailureUI(self, self.__tr(
"<b>Printer Error.</b><p>Printer is busy, offline, or in an error state. Please check the device and try again."))
d.close()
#
# Remove Page
#
def initRemovePage(self):
pass
def showRemovePage(self):
self.displayPage(PAGE_REMOVE)
self.StepText.setText(self.__tr("Step 1 of 1"))
self.setNextButton(BUTTON_REMOVE)
self.BackButton.setEnabled(False)
self.NextButton.setEnabled(False)
self.RemoveDevicesTableWidget.verticalHeader().hide()
self.installed_printers = device.getSupportedCUPSPrinters([
'hp', 'hpfax'])
log.debug(self.installed_printers)
if not self.installed_printers:
FailureUI(self, self.__tr(
"<b>No printers or faxes found to remove.</b><p>You must setup a least one printer or fax before you can remove it."))
self.close()
return
self.RemoveDevicesTableWidget.setRowCount(len(self.installed_printers))
headers = [self.__tr("Select"), self.__tr(
'Printer (Queue) Name'), self.__tr('Type'), self.__tr('Device URI')]
self.RemoveDevicesTableWidget.setColumnCount(len(headers))
self.RemoveDevicesTableWidget.setHorizontalHeaderLabels(headers)
flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled
row = 0
for p in self.installed_printers:
widget = QCheckBox(self.RemoveDevicesTableWidget)
widget.stateChanged.connect(self.CheckBox_stateChanged)
self.RemoveDevicesTableWidget.setCellWidget(row, 0, widget)
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
device.parseDeviceURI(p.device_uri)
if self.device_uri is not None and self.device_uri == p.device_uri:
widget.setCheckState(Qt.Checked)
i = QTableWidgetItem(str(p.name))
i.setFlags(flags)
i.setData(Qt.UserRole, p.name)
self.RemoveDevicesTableWidget.setItem(row, 1, i)
if back_end == 'hpfax':
typ = self.__tr("Fax")
else:
typ = self.__tr("Printer")
i = QTableWidgetItem(typ)
i.setFlags(flags)
self.RemoveDevicesTableWidget.setItem(row, 2, i)
i = QTableWidgetItem(str(p.device_uri))
i.setFlags(flags)
self.RemoveDevicesTableWidget.setItem(row, 3, i)
row += 1
self.RemoveDevicesTableWidget.resizeColumnsToContents()
def CheckBox_stateChanged(self, i):
for row in range(self.RemoveDevicesTableWidget.rowCount()):
widget = self.RemoveDevicesTableWidget.cellWidget(row, 0)
if widget.checkState() == Qt.Checked:
self.NextButton.setEnabled(True)
break
else:
self.NextButton.setEnabled(False)
#
# Misc
#
def NextButton_clicked(self):
p = self.StackedWidget.currentIndex()
if p == PAGE_DISCOVERY:
self.manual = self.ManualGroupBox.isChecked()
self.param = to_unicode(self.ManualParamLineEdit.text())
self.jd_port = self.JetDirectSpinBox.value()
self.search = to_unicode(self.SearchLineEdit.text())
self.device_desc = value_int(self.DeviceTypeComboBox.itemData(
self.DeviceTypeComboBox.currentIndex()))[0]
self.discovery_method = self.NetworkDiscoveryMethodComboBox.currentIndex()
if self.WirelessButton.isChecked():
dlg = WifiSetupDialog(self, device_uri=None, standalone=False)
dlg.exec_()
if dlg.success == SUCCESS_CONNECTED:
self.manual = True
self.param = dlg.hn
self.bus = 'net'
if not self.WirelessButton.isChecked():
self.showDevicesPage()
elif p == PAGE_DEVICES:
row = self.DevicesTableWidget.currentRow()
self.device_uri = self.DevicesTableWidget.item(row, 0).device_uri
self.mq = device.queryModelByURI(self.device_uri)
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(
self.device_uri)
self.model = models.normalizeModelName(model).lower()
self.showAddPrinterPage()
elif p == PAGE_ADD_PRINTER:
self.print_test_page = self.SendTestPageCheckBox.isChecked()
self.print_setup = self.SetupPrintGroupBox.isChecked()
self.fax_setup = self.SetupFaxGroupBox.isChecked()
self.print_location = from_unicode_to_str(
to_unicode(self.PrinterLocationLineEdit.text()))
self.print_desc = from_unicode_to_str(
to_unicode(self.PrinterDescriptionLineEdit.text()))
self.fax_desc = from_unicode_to_str(
to_unicode(self.FaxDescriptionLineEdit.text()))
self.fax_location = from_unicode_to_str(
to_unicode(self.FaxLocationLineEdit.text()))
#self.fax_name_company = to_unicode(self.NameCompanyLineEdit.text())
#self.fax_number = to_unicode(self.FaxNumberLineEdit.text())
self.addPrinter()
elif p == PAGE_REMOVE:
for row in range(self.RemoveDevicesTableWidget.rowCount()):
widget = self.RemoveDevicesTableWidget.cellWidget(row, 0)
if widget.checkState() == Qt.Checked:
item = self.RemoveDevicesTableWidget.item(row, 1)
printer = to_unicode(value_str(item.data(Qt.UserRole)))
uri = device.getDeviceURIByPrinterName(printer)
log.debug("Removing printer: %s" % printer)
status, status_str = cups.cups_operation(
cups.delPrinter, GUI_MODE, 'qt4', self, printer)
if status != cups.IPP_OK:
FailureUI(self, self.__tr(
"<b>Unable to delete '%s' queue. </b><p>Error : %s" % (printer, status_str)))
if status == cups.IPP_FORBIDDEN or status == cups.IPP_NOT_AUTHENTICATED or status == cups.IPP_NOT_AUTHORIZED:
break
else:
# sending Event to add this device in hp-systray
utils.sendEvent(
EVENT_CUPS_QUEUES_REMOVED, uri, printer)
self.close()
else:
log.error("Invalid page!") # shouldn't happen!
def BackButton_clicked(self):
p = self.StackedWidget.currentIndex()
if p == PAGE_DEVICES:
self.devices = {}
self.showDiscoveryPage()
elif p == PAGE_ADD_PRINTER:
self.showDevicesPage()
else:
log.error("Invalid page!") # shouldn't happen!
def CancelButton_clicked(self):
self.close()
def displayPage(self, page):
self.StackedWidget.setCurrentIndex(page)
self.updateStepText(page)
def setNextButton(self, typ=BUTTON_FINISH):
if typ == BUTTON_ADD_PRINTER:
self.NextButton.setText(self.__tr("Add Printer"))
elif typ == BUTTON_NEXT:
self.NextButton.setText(self.__tr("Next >"))
elif typ == BUTTON_FINISH:
self.NextButton.setText(self.__tr("Finish"))
elif typ == BUTTON_REMOVE:
self.NextButton.setText(self.__tr("Remove"))
def updateStepText(self, p):
self.StepText.setText(self.__tr("Step %s of %s" %
(p+1, self.max_page+1))) # Python 3.2
def __tr(self, s, c=None):
return qApp.translate("SetupDialog", s, c)