1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# 4# (c) Copyright 2001-2015 HP Development Company, L.P. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19# 20# Authors: Don Welch, Naga Samrat Chowdary Narla 21# 22 23# StdLib 24import socket 25import operator 26import subprocess 27import signal 28 29# Local 30from base.g import * 31from base import device, utils, models, pkit 32from prnt import cups 33from base.codes import * 34from .ui_utils import * 35from installer import pluginhandler 36from base.sixext import to_unicode, PY3, from_unicode_to_str 37# Qt 38try: 39 from PyQt5.QtCore import * 40 from PyQt5.QtGui import * 41except ImportError: 42 from PyQt5.QtCore import * 43 from PyQt5.QtGui import * 44 from PyQt5.QtWidgets import * 45 46 47# Ui 48from .setupdialog_base import Ui_Dialog 49from .plugindialog import PluginDialog 50from .wifisetupdialog import WifiSetupDialog, SUCCESS_CONNECTED 51 52# Fax 53try: 54 from fax import fax 55 fax_import_ok = True 56except ImportError: 57 # This can fail on Python < 2.3 due to the datetime module 58 fax_import_ok = False 59 log.warning("Fax setup disabled - Python 2.3+ required.") 60 61 62PAGE_DISCOVERY = 0 63PAGE_DEVICES = 1 64PAGE_ADD_PRINTER = 2 65PAGE_REMOVE = 3 66 67 68BUTTON_NEXT = 0 69BUTTON_FINISH = 1 70BUTTON_ADD_PRINTER = 2 71BUTTON_REMOVE = 3 72 73ADVANCED_SHOW = 0 74ADVANCED_HIDE = 1 75 76DEVICE_DESC_ALL = 0 77DEVICE_DESC_SINGLE_FUNC = 1 78DEVICE_DESC_MULTI_FUNC = 2 79 80 81class PasswordDialog(QDialog): 82 def __init__(self, prompt, parent=None, name=None, modal=0, fl=0): 83 QDialog.__init__(self, parent) 84 # Application icon 85 self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128'))) 86 self.prompt = prompt 87 88 Layout= QGridLayout(self) 89 Layout.setContentsMargins(11, 11, 11, 11) 90 Layout.setSpacing(6) 91 92 self.PromptTextLabel = QLabel(self) 93 Layout.addWidget(self.PromptTextLabel,0,0,1,3) 94 95 self.UsernameTextLabel = QLabel(self) 96 Layout.addWidget(self.UsernameTextLabel,1,0) 97 98 self.UsernameLineEdit = QLineEdit(self) 99 self.UsernameLineEdit.setEchoMode(QLineEdit.Normal) 100 Layout.addWidget(self.UsernameLineEdit,1,1,1,2) 101 102 self.PasswordTextLabel = QLabel(self) 103 Layout.addWidget(self.PasswordTextLabel,2,0) 104 105 self.PasswordLineEdit = QLineEdit(self) 106 self.PasswordLineEdit.setEchoMode(QLineEdit.Password) 107 Layout.addWidget(self.PasswordLineEdit,2,1,1,2) 108 109 self.OkPushButton = QPushButton(self) 110 Layout.addWidget(self.OkPushButton,3,2) 111 112 self.languageChange() 113 114 self.resize(QSize(420,163).expandedTo(self.minimumSizeHint())) 115 116 self.OkPushButton.clicked.connect(self.accept) 117 self.PasswordLineEdit.returnPressed.connect(self.accept) 118 119 def setDefaultUsername(self, defUser, allowUsernameEdit = True): 120 self.UsernameLineEdit.setText(defUser) 121 if not allowUsernameEdit: 122 self.UsernameLineEdit.setReadOnly(True) 123 self.UsernameLineEdit.setStyleSheet("QLineEdit {background-color: lightgray}") 124 125 def getUsername(self): 126 return to_unicode(self.UsernameLineEdit.text()) 127 128 129 def getPassword(self): 130 return to_unicode(self.PasswordLineEdit.text()) 131 132 133 def languageChange(self): 134 self.setWindowTitle(self.__tr("HP Device Manager - Enter Username/Password")) 135 self.PromptTextLabel.setText(self.__tr(self.prompt)) 136 self.UsernameTextLabel.setText(self.__tr("Username:")) 137 self.PasswordTextLabel.setText(self.__tr("Password:")) 138 self.OkPushButton.setText(self.__tr("OK")) 139 140 141 def __tr(self,s,c = None): 142 return qApp.translate("SetupDialog",s,c) 143 144 145def FailureMessageUI(prompt): 146 try: 147 dlg = PasswordDialog(prompt, None) 148 FailureUI(dlg, prompt) 149 finally: 150 pass 151 152 153def showPasswordUI(prompt, userName=None, allowUsernameEdit=True): 154 try: 155 dlg = PasswordDialog(prompt, None) 156 157 if userName != None: 158 dlg.setDefaultUsername(userName, allowUsernameEdit) 159 160 if dlg.exec_() == QDialog.Accepted: 161 return (dlg.getUsername(), dlg.getPassword()) 162 163 finally: 164 pass 165 166 return ("", "") 167 168 169 170class DeviceTableWidgetItem(QTableWidgetItem): 171 def __init__(self, text, device_uri): 172 QTableWidgetItem.__init__(self, text, QTableWidgetItem.UserType) 173 self.device_uri = device_uri 174 175 176 177class SetupDialog(QDialog, Ui_Dialog): 178 def __init__(self, parent, param, jd_port, device_uri=None, remove=False): 179 QDialog.__init__(self, parent) 180 self.setupUi(self) 181 182 self.param = param 183 self.jd_port = jd_port 184 self.device_uri = device_uri 185 self.remove = remove 186 187 if device_uri: 188 log.info("Using device: %s" % device_uri) 189 190 self.initUi() 191 192 if self.remove: 193 QTimer.singleShot(0, self.showRemovePage) 194 else: 195 if self.skip_discovery: 196 self.discovery_method = 0 # SLP 197 QTimer.singleShot(0, self.showDevicesPage) 198 else: 199 QTimer.singleShot(0, self.showDiscoveryPage) 200 201 cups.setPasswordCallback(showPasswordUI) 202 203 204 # 205 # INIT 206 # 207 208 def initUi(self): 209 self.setWindowIcon(QIcon(load_pixmap('hp_logo', '128x128'))) 210 211 # connect signals/slots 212 self.CancelButton.clicked.connect(self.CancelButton_clicked) 213 self.BackButton.clicked.connect(self.BackButton_clicked) 214 self.NextButton.clicked.connect(self.NextButton_clicked) 215 self.ManualGroupBox.clicked.connect(self.ManualGroupBox_clicked) 216 signal.signal(signal.SIGINT, signal.SIG_DFL) 217 218 if self.remove: 219 self.initRemovePage() 220 self.max_page = 1 221 else: 222 self.initDiscoveryPage() 223 self.initDevicesPage() 224 self.initAddPrinterPage() 225 self.max_page = PAGE_ADD_PRINTER 226 227 # 228 # DISCOVERY PAGE 229 # 230 231 def initDiscoveryPage(self): 232 self.UsbRadioButton.setChecked(True) 233 self.setUsbRadioButton(True) 234 self.ManualGroupBox.setChecked(False) 235 236 self.advanced = False 237 self.manual = False 238 self.skip_discovery = False 239 self.discovery_method = 0 240 self.NetworkRadioButton.setEnabled(prop.net_build) 241 self.WirelessButton.setEnabled(prop.net_build) 242 self.ParallelRadioButton.setEnabled(prop.par_build) 243 self.devices = {} 244 self.bus = 'usb' 245 self.timeout = 5 246 self.ttl = 4 247 self.search = '' 248 self.print_test_page = False 249 self.device_desc = DEVICE_DESC_ALL 250 251 if self.param: 252 log.info("Searching for device...") 253 self.manual = True 254 self.advanced = True 255 self.ManualParamLineEdit.setText(self.param) 256 self.JetDirectSpinBox.setValue(self.jd_port) 257 self.ManualGroupBox.setChecked(True) 258 self.DiscoveryOptionsGroupBox.setEnabled(False) 259 260 if self.manualDiscovery(): 261 self.skip_discovery = True 262 else: 263 FailureUI(self, self.__tr("<b>Device not found.</b> <p>Please make sure your printer is properly connected and powered-on.")) 264 265 match = device.usb_pat.match(self.param) 266 if match is not None: 267 self.UsbRadioButton.setChecked(True) 268 self.setUsbRadioButton(True) 269 270 else: 271 match = device.dev_pat.match(self.param) 272 if match is not None and prop.par_build: 273 self.ParallelRadioButton.setChecked(True) 274 self.setParallelRadioButton(True) 275 276 else: 277 match = device.ip_pat.match(self.param) 278 if match is not None and prop.net_build: 279 self.NetworkRadioButton.setChecked(True) 280 self.setNetworkRadioButton(True) 281 282 else: 283 FailureUI(self, self.__tr("<b>Invalid manual discovery parameter.</b>")) 284 285 elif self.device_uri: # If device URI specified on the command line, skip discovery 286 # if the device URI is well-formed (but not necessarily valid) 287 try: 288 back_end, is_hp, self.bus, model, serial, dev_file, host, zc, port = \ 289 device.parseDeviceURI(self.device_uri) 290 291 except Error: 292 log.error("Invalid device URI specified: %s" % self.device_uri) 293 294 else: 295 name = host 296 if self.bus == 'net': 297 try: 298 log.debug("Trying to get hostname for device...") 299 name = socket.gethostbyaddr(host)[0] 300 except socket.herror: 301 log.debug("Failed.") 302 else: 303 log.debug("Host name=%s" % name) 304 305 self.devices = {self.device_uri : (model, model, name)} 306 self.skip_discovery = True 307 308 # If no network or parallel, usb is only option, skip initial page... 309 elif not prop.par_build and not prop.net_build: 310 self.skip_discovery = True 311 self.bus = 'usb' 312 self.UsbRadioButton.setChecked(True) 313 self.setUsbRadioButton(True) 314 315 if prop.fax_build and prop.scan_build: 316 self.DeviceTypeComboBox.addItem("All devices/printers", DEVICE_DESC_ALL) 317 self.DeviceTypeComboBox.addItem("Single function printers only", DEVICE_DESC_SINGLE_FUNC) 318 self.DeviceTypeComboBox.addItem("All-in-one/MFP devices only", DEVICE_DESC_MULTI_FUNC) 319 else: 320 self.DeviceTypeComboBox.setEnabled(False) 321 322 self.AdvancedButton.clicked.connect(self.AdvancedButton_clicked) 323 self.UsbRadioButton.toggled.connect(self.UsbRadioButton_toggled) 324 self.NetworkRadioButton.toggled.connect(self.NetworkRadioButton_toggled) 325 self.WirelessButton.toggled.connect(self.WirelessButton_toggled) 326 self.ParallelRadioButton.toggled.connect(self.ParallelRadioButton_toggled) 327 self.NetworkTTLSpinBox.valueChanged.connect(self.NetworkTTLSpinBox_valueChanged) 328 self.NetworkTimeoutSpinBox.valueChanged.connect(self.NetworkTimeoutSpinBox_valueChanged) 329 self.ManualGroupBox.toggled.connect(self.ManualGroupBox_toggled) 330 331 self.showAdvanced() 332 333 334 def ManualGroupBox_toggled(self, checked): 335 self.DiscoveryOptionsGroupBox.setEnabled(not checked) 336 337 338 def manualDiscovery(self): 339 # Validate param... 340 device_uri, sane_uri, fax_uri = device.makeURI(self.param, self.jd_port) 341 342 if device_uri: 343 log.info("Found device: %s" % device_uri) 344 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \ 345 device.parseDeviceURI(device_uri) 346 347 name = host 348 if bus == 'net': 349 try: 350 if device.ip_pat.search(name) is not None: 351 log.debug("Getting host name from IP address (%s)" % name) 352 name = socket.gethostbyaddr(host)[0] 353 except (socket.herror, socket.gaierror): 354 pass 355 356 self.devices = {device_uri : (model, model, name)} 357 358 if bus == 'usb': 359 self.UsbRadioButton.setChecked(True) 360 self.setUsbRadioButton(True) 361 362 elif bus == 'net' and prop.net_build: 363 self.NetworkRadioButton.setChecked(True) 364 self.setNetworkRadioButton(True) 365 366 elif bus == 'par' and prop.par_build: 367 self.ParallelRadioButton.setChecked(True) 368 self.setParallelRadioButton(True) 369 370 return True 371 372 373 return False 374 375 376 def ManualGroupBox_clicked(self, checked): 377 self.manual = checked 378 network = self.NetworkRadioButton.isChecked() 379 self.setJetDirect(network) 380 381 382 def showDiscoveryPage(self): 383 self.BackButton.setEnabled(False) 384 self.NextButton.setEnabled(True) 385 self.setNextButton(BUTTON_NEXT) 386 self.displayPage(PAGE_DISCOVERY) 387 388 389 def AdvancedButton_clicked(self): 390 self.advanced = not self.advanced 391 self.showAdvanced() 392 393 394 def showAdvanced(self): 395 if self.advanced: 396 self.AdvancedStackedWidget.setCurrentIndex(ADVANCED_SHOW) 397 self.AdvancedButton.setText(self.__tr("Hide Advanced Options")) 398 self.AdvancedButton.setIcon(QIcon(load_pixmap("minus", "16x16"))) 399 else: 400 self.AdvancedStackedWidget.setCurrentIndex(ADVANCED_HIDE) 401 self.AdvancedButton.setText(self.__tr("Show Advanced Options")) 402 self.AdvancedButton.setIcon(QIcon(load_pixmap("plus", "16x16"))) 403 404 405 def setJetDirect(self, enabled): 406 self.JetDirectLabel.setEnabled(enabled and self.manual) 407 self.JetDirectSpinBox.setEnabled(enabled and self.manual) 408 409 410 def setNetworkOptions(self, enabled): 411 self.NetworkTimeoutLabel.setEnabled(enabled) 412 self.NetworkTimeoutSpinBox.setEnabled(enabled) 413 self.NetworkTTLLabel.setEnabled(enabled) 414 self.NetworkTTLSpinBox.setEnabled(enabled) 415 416 417 def setSearchOptions(self, enabled): 418 self.SearchLineEdit.setEnabled(enabled) 419 self.DeviceTypeComboBox.setEnabled(enabled) 420 self.DeviceTypeLabel.setEnabled(enabled) 421 422 423 def setManualDiscovery(self, enabled): 424 self.ManualGroupBox.setEnabled(enabled) 425 426 427 def setNetworkDiscovery(self, enabled): 428 self.NetworkDiscoveryMethodLabel.setEnabled(enabled) 429 self.NetworkDiscoveryMethodComboBox.setEnabled(enabled) 430 self.NetworkDiscoveryMethodComboBox.setCurrentIndex(0) 431 432 433 def UsbRadioButton_toggled(self, radio_enabled): 434 self.setUsbRadioButton(radio_enabled) 435 436 437 def setUsbRadioButton(self, checked): 438 self.setNetworkDiscovery(not checked) 439 self.setJetDirect(not checked) 440 self.setNetworkOptions(not checked) 441 self.setSearchOptions(checked) 442 self.setManualDiscovery(checked) 443 444 if checked: 445 self.ManualParamLabel.setText(self.__tr("USB bus ID:device ID (bbb:ddd):")) 446 self.bus = 'usb' 447 # TODO: Set bbb:ddd validator 448 449 450 def NetworkRadioButton_toggled(self, radio_enabled): 451 self.setNetworkRadioButton(radio_enabled) 452 453 454 def setNetworkRadioButton(self, checked): 455 self.setNetworkDiscovery(checked) 456 self.setJetDirect(checked) 457 self.setNetworkOptions(checked) 458 self.setSearchOptions(checked) 459 self.setManualDiscovery(checked) 460 461 462 if checked: 463 self.ManualParamLabel.setText(self.__tr("IP Address or network name:")) 464 self.bus = 'net' 465 # TODO: Reset validator 466 467 def WirelessButton_toggled(self, radio_enabled): 468 self.setWirelessButton(radio_enabled) 469 470 471 def setWirelessButton(self, checked): 472 self.setNetworkDiscovery(not checked) 473 self.setJetDirect(not checked) 474 self.setNetworkOptions(not checked) 475 self.setSearchOptions(not checked) 476 self.setManualDiscovery(not checked) 477 478 479 if checked: 480 self.ManualParamLabel.setText(self.__tr("IP Address or network name:")) 481 self.bus = 'net' 482 483 484 def ParallelRadioButton_toggled(self, radio_enabled): 485 self.setParallelRadioButton(radio_enabled) 486 487 488 def setParallelRadioButton(self, checked): 489 self.setNetworkDiscovery(not checked) 490 self.setJetDirect(not checked) 491 self.setNetworkOptions(not checked) 492 self.setSearchOptions(not checked) 493 self.setManualDiscovery(not checked) 494 495 496 if checked: 497 self.ManualParamLabel.setText(self.__tr("Device node (/dev/...):")) 498 self.bus = 'par' 499 # TODO: Set /dev/... validator 500 501 502 def NetworkTTLSpinBox_valueChanged(self, ttl): 503 self.ttl = ttl 504 505 506 def NetworkTimeoutSpinBox_valueChanged(self, timeout): 507 self.timeout = timeout 508 509 # 510 # DEVICES PAGE 511 # 512 513 def initDevicesPage(self): 514 self.RefreshButton.clicked.connect(self.RefreshButton_clicked) 515 516 517 def showDevicesPage(self): 518 self.BackButton.setEnabled(True) 519 self.setNextButton(BUTTON_NEXT) 520 search = "" 521 522 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 523 try: 524 if not self.devices: 525 if self.manual and self.param: # manual, but not passed-in on command line 526 self.manualDiscovery() 527 528 else: # probe 529 net_search_type = '' 530 531 if self.bus == 'net': 532 if self.discovery_method == 0: 533 net_search_type = "slp" 534 elif self.discovery_method == 1: 535 net_search_type = "mdns" 536 else: 537 net_search_type = "avahi" 538 539 log.info("Searching... (bus=%s, timeout=%d, ttl=%d, search=%s desc=%d, method=%s)" % 540 (self.bus, self.timeout, self.ttl, self.search or "(None)", 541 self.device_desc, net_search_type)) 542 else: 543 log.info("Searching... (bus=%s, search=%s, desc=%d)" % 544 (self.bus, self.search or "(None)", self.device_desc)) 545 546 if self.device_desc == DEVICE_DESC_SINGLE_FUNC: 547 filter_dict = {'scan-type' : (operator.le, SCAN_TYPE_NONE)} 548 549 elif self.device_desc == DEVICE_DESC_MULTI_FUNC: 550 filter_dict = {'scan-type': (operator.gt, SCAN_TYPE_NONE)} 551 552 else: # DEVICE_DESC_ALL 553 filter_dict = {} 554 555 if self.bus == 'usb': 556 try: 557 from base import smart_install 558 except ImportError: 559 log.error("Failed to Import smart_install.py from base") 560 else: #if no Smart Install device found, ignores. 561 QApplication.restoreOverrideCursor() 562 smart_install.disable(GUI_MODE, 'qt4') 563 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 564 565 self.devices = device.probeDevices([self.bus], self.timeout, self.ttl, 566 filter_dict, self.search, net_search=net_search_type) 567 568 finally: 569 QApplication.restoreOverrideCursor() 570 571 self.clearDevicesTable() 572 573 if self.devices: 574 self.NextButton.setEnabled(True) 575 self.DevicesFoundIcon.setPixmap(load_pixmap('info', '16x16')) 576 577 if len(self.devices) == 1: 578 self.DevicesFoundLabel.setText(self.__tr("<b>1 device found.</b> Click <i>Next</i> to continue.")) 579 else: 580 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)))) 581 582 self.loadDevicesTable() 583 584 else: 585 self.NextButton.setEnabled(False) 586 self.DevicesFoundIcon.setPixmap(load_pixmap('error', '16x16')) 587 log.error("No devices found on bus: %s" % self.bus) 588 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.")) 589 if self.bus == 'net' and utils.check_lan(): 590 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. 591 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. 592 <b>http://hplipopensource.com/node/374</b></p>'''), 593 self.__tr("HP Device Manager")) 594 595 596 self.displayPage(PAGE_DEVICES) 597 598 599 def loadDevicesTable(self): 600 self.DevicesTableWidget.setRowCount(len(self.devices)) 601 602 if self.bus == 'net': 603 if self.discovery_method == 0: 604 headers = [self.__tr('Model'), self.__tr('IP Address'), self.__tr('Host Name'), self.__tr('Device URI')] 605 device_uri_col = 3 606 else: 607 headers = [self.__tr('Model'), self.__tr('Host Name'), self.__tr('Device URI')] 608 device_uri_col = 2 609 else: 610 headers = [self.__tr('Model'), self.__tr('Device URI')] 611 device_uri_col = 1 612 613 self.DevicesTableWidget.setColumnCount(len(headers)) 614 self.DevicesTableWidget.setHorizontalHeaderLabels(headers) 615 flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled 616 617 for row, d in enumerate(self.devices): 618 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(d) 619 model_ui = models.normalizeModelUIName(model) 620 621 i = DeviceTableWidgetItem(str(model_ui), d) 622 i.setFlags(flags) 623 self.DevicesTableWidget.setItem(row, 0, i) 624 625 i = QTableWidgetItem(str(d)) 626 i.setFlags(flags) 627 self.DevicesTableWidget.setItem(row, device_uri_col, i) 628 629 if self.bus == 'net': 630 i = QTableWidgetItem(str(host)) 631 i.setFlags(flags) 632 self.DevicesTableWidget.setItem(row, 1, i) 633 634 if self.discovery_method == 0: 635 i = QTableWidgetItem(str(self.devices[d][2])) 636 i.setFlags(flags) 637 self.DevicesTableWidget.setItem(row, 2, i) 638 639 self.DevicesTableWidget.resizeColumnsToContents() 640 self.DevicesTableWidget.selectRow(0) 641 self.DevicesTableWidget.setSortingEnabled(True) 642 self.DevicesTableWidget.sortItems(0) 643 644 645 def clearDevicesTable(self): 646 self.DevicesTableWidget.clear() 647 self.DevicesTableWidget.setRowCount(0) 648 self.DevicesTableWidget.setColumnCount(0) 649 650 651 def RefreshButton_clicked(self): 652 self.clearDevicesTable() 653 self.devices = [] 654 QTimer.singleShot(0, self.showDevicesPage) 655 656 # 657 # ADD PRINTER PAGE 658 # 659 660 def initAddPrinterPage(self): 661 self.mq = {} 662 663 self.PrinterNameLineEdit.textEdited.connect(self.PrinterNameLineEdit_textEdited) 664 665 self.FaxNameLineEdit.textEdited.connect(self.FaxNameLineEdit_textEdited) 666 667 self.SetupPrintGroupBox.clicked.connect(self.SetupPrintGroupBox_clicked) 668 self.SetupFaxGroupBox.clicked.connect(self.SetupFaxGroupBox_clicked) 669 self.PrinterNameLineEdit.setValidator(PrinterNameValidator(self.PrinterNameLineEdit)) 670 self.FaxNameLineEdit.setValidator(PrinterNameValidator(self.FaxNameLineEdit)) 671 self.FaxNumberLineEdit.setValidator(PhoneNumValidator(self.FaxNumberLineEdit)) 672 self.OtherPPDButton.setIcon(QIcon(load_pixmap('folder_open', '16x16'))) 673 self.OtherPPDButton.clicked.connect(self.OtherPPDButton_clicked) 674 675 self.OtherPPDButton.setToolTip(self.__tr("Browse for an alternative PPD file for this printer.")) 676 677 self.printer_fax_names_same = False 678 self.printer_name = '' 679 self.fax_name = '' 680 self.fax_setup_ok = True 681 self.fax_setup = False 682 self.print_setup = False 683 684 685 def showAddPrinterPage(self): 686 # Install the plugin if needed... 687 pluginObj = pluginhandler.PluginHandle() 688 plugin = self.mq.get('plugin', PLUGIN_NONE) 689 plugin_reason = self.mq.get('plugin-reason', PLUGIN_REASON_NONE) 690 if plugin > PLUGIN_NONE: 691 692 if pluginObj.getStatus() != pluginhandler.PLUGIN_INSTALLED: 693 ok, sudo_ok = pkit.run_plugin_command(plugin == PLUGIN_REQUIRED, plugin_reason) 694 if not sudo_ok: 695 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>")) 696 return 697 if not ok or pluginObj.getStatus() != pluginhandler.PLUGIN_INSTALLED: 698 if plugin == PLUGIN_REQUIRED: 699 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>")) 700 return 701 else: 702 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.")) 703 704 self.setNextButton(BUTTON_ADD_PRINTER) 705 self.print_setup = self.setDefaultPrinterName() 706 if self.print_setup: 707 self.SetupPrintGroupBox.setCheckable(True) 708 self.SetupPrintGroupBox.setEnabled(True) 709 self.SendTestPageCheckBox.setCheckable(True) 710 self.SendTestPageCheckBox.setEnabled(True) 711 self.findPrinterPPD() 712 self.updatePPD() 713 else: 714 self.print_ppd = None 715 self.SetupPrintGroupBox.setCheckable(False) 716 self.SetupPrintGroupBox.setEnabled(False) 717 self.SendTestPageCheckBox.setCheckable(False) 718 self.SendTestPageCheckBox.setEnabled(False) 719 720 if fax_import_ok and prop.fax_build and \ 721 self.mq.get('fax-type', FAX_TYPE_NONE) not in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED): 722 self.fax_setup = True 723 self.SetupFaxGroupBox.setChecked(True) 724 self.SetupFaxGroupBox.setEnabled(True) 725 726 self.fax_setup = self.setDefaultFaxName() 727 if self.fax_setup: 728 self.findFaxPPD() 729 self.readwriteFaxInformation() 730 else: 731 self.fax_setup = False 732 self.SetupFaxGroupBox.setChecked(False) 733 self.SetupFaxGroupBox.setEnabled(False) 734 735 else: 736 self.SetupFaxGroupBox.setChecked(False) 737 self.SetupFaxGroupBox.setEnabled(False) 738 self.fax_name = '' 739 self.fax_name_ok = True 740 self.fax_setup = False 741 self.fax_setup_ok = True 742 743 744 745 if self.print_setup or self.fax_setup: 746 self.setAddPrinterButton() 747 self.displayPage(PAGE_ADD_PRINTER) 748 else: 749 log.info("Exiting the setup...") 750 self.close() 751 752 753 754 755 def updatePPD(self): 756 if self.print_ppd is None: 757 log.error("No appropriate print PPD file found for model %s" % self.model) 758 self.PPDFileLineEdit.setText(self.__tr('(Not found. Click browse button to select a PPD file.)')) 759 try: 760 self.PPDFileLineEdit.setStyleSheet("background-color: yellow") 761 except AttributeError: 762 pass 763 self.PrinterDescriptionLineEdit.setText(str("")) 764 765 else: 766 self.PPDFileLineEdit.setText(self.print_ppd[0]) 767 self.PrinterDescriptionLineEdit.setText(self.print_ppd[1]) 768 try: 769 self.PPDFileLineEdit.setStyleSheet("") 770 except AttributeError: 771 pass 772 773 774 def OtherPPDButton_clicked(self, b): 775 ppd_file = to_unicode(QFileDialog.getOpenFileName(self, self.__tr("Select PPD File"), 776 sys_conf.get('dirs', 'ppd'), 777 self.__tr("PPD Files (*.ppd *.ppd.gz);;All Files (*)"))) 778 779 if ppd_file and os.path.exists(ppd_file): 780 self.print_ppd = (ppd_file, cups.getPPDDescription(ppd_file)) 781 self.updatePPD() 782 self.setAddPrinterButton() 783 784 785 def findPrinterPPD(self): 786 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 787 try: 788 self.print_ppd = None 789 self.ppds = cups.getSystemPPDs() 790 self.print_ppd = cups.getPPDFile2(self.mq, self.model, self.ppds) 791 if "scanjet" in self.model or "digital_sender" in self.model: 792 self.print_ppd = None 793 794 finally: 795 QApplication.restoreOverrideCursor() 796 797 798 def findFaxPPD(self): 799 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 800 try: 801 self.fax_ppd, fax_ppd_name, nick = cups.getFaxPPDFile(self.mq, self.model) 802 if self.fax_ppd: 803 self.fax_setup_ok = True 804 else: 805 self.fax_setup_ok = False 806 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)) 807 self.fax_setup = False 808 self.SetupFaxGroupBox.setChecked(False) 809 self.SetupFaxGroupBox.setEnabled(False) 810 finally: 811 QApplication.restoreOverrideCursor() 812 813 814 def setDefaultPrinterName(self): 815 self.installed_print_devices = device.getSupportedCUPSDevices(['hp']) 816 log.debug(self.installed_print_devices) 817 818 self.installed_queues = [p.name for p in cups.getPrinters()] 819 820 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.device_uri) 821 default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_') 822 823 printer_name = default_model 824 installed_printer_names = device.getSupportedCUPSPrinterNames(['hp']) 825 # Check for duplicate names 826 if (self.device_uri in self.installed_print_devices and printer_name in self.installed_print_devices[self.device_uri]) \ 827 or (printer_name in installed_printer_names): 828 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>" % 829 ', '.join([printer for printer in installed_printer_names if printer_name in printer])) 830 if ( QMessageBox.warning(self, 831 self.windowTitle(), 832 warn_text, 833 QMessageBox.Yes|\ 834 QMessageBox.No, 835 QMessageBox.NoButton) == QMessageBox.Yes ): 836 837 i = 2 838 while True: 839 t = printer_name + "_%d" % i 840 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]): 841 printer_name += "_%d" % i 842 break 843 i += 1 844 else: 845 self.printer_name_ok = False 846 return False 847 848 self.printer_name_ok = True 849 self.PrinterNameLineEdit.setText(printer_name) 850 log.debug(printer_name) 851 self.printer_name = printer_name 852 return True 853 854 855 def setDefaultFaxName(self): 856 self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax']) 857 log.debug(self.installed_fax_devices) 858 859 self.fax_uri = self.device_uri.replace('hp:', 'hpfax:') 860 861 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.fax_uri) 862 default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_') 863 864 fax_name = default_model + "_fax" 865 installed_fax_names = device.getSupportedCUPSPrinterNames(['hpfax']) 866 # Check for duplicate names 867 if (self.fax_uri in self.installed_fax_devices and fax_name in self.installed_fax_devices[self.fax_uri]) \ 868 or (fax_name in installed_fax_names): 869 warn_text = self.__tr( 870 "<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>" % 871 ', '.join([fax_device for fax_device in installed_fax_names if fax_name in fax_device])) 872 if ( QMessageBox.warning(self, 873 self.windowTitle(), 874 warn_text, 875 QMessageBox.Yes|\ 876 QMessageBox.No|\ 877 QMessageBox.NoButton) == QMessageBox.Yes ): 878 i = 2 879 while True: 880 t = fax_name + "_%d" % i 881 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]): 882 fax_name += "_%d" % i 883 break 884 i += 1 885 else: 886 self.fax_name_ok = False 887 return False 888 889 self.fax_name_ok = True 890 self.FaxNameLineEdit.setText(fax_name) 891 self.fax_name = fax_name 892 return True 893 894 895 def PrinterNameLineEdit_textEdited(self, t): 896 self.printer_name = to_unicode(t) 897 self.printer_name_ok = True 898 899 if not self.printer_name: 900 self.PrinterNameLineEdit.setToolTip(self.__tr('You must enter a name for the printer.')) 901 self.printer_name_ok = False 902 903 elif self.fax_name == self.printer_name: 904 s = self.__tr('The printer name and fax name must be different. Please choose different names.') 905 self.PrinterNameLineEdit.setToolTip(s) 906 self.FaxNameLineEdit.setToolTip(s) 907 self.fax_name_ok = False 908 self.printer_name_ok = False 909 self.printer_fax_names_same = True 910 911 elif self.printer_name in self.installed_queues: 912 self.PrinterNameLineEdit.setToolTip(self.__tr('A printer already exists with this name. Please choose a different name.')) 913 self.printer_name_ok = False 914 915 elif self.printer_fax_names_same: 916 if self.fax_name != self.printer_name: 917 self.printer_fax_names_same = False 918 self.printer_name_ok = True 919 920 self.FaxNameLineEdit.emit(SIGNAL("textEdited(const QString &)"), 921 self.FaxNameLineEdit.text()) 922 923 self.setIndicators() 924 self.setAddPrinterButton() 925 926 927 def FaxNameLineEdit_textEdited(self, t): 928 self.fax_name = to_unicode(t) 929 self.fax_name_ok = True 930 931 if not self.fax_name: 932 self.FaxNameLineEdit.setToolTip(self.__tr('You must enter a fax name.')) 933 self.fax_name_ok = False 934 935 elif self.fax_name == self.printer_name: 936 s = self.__tr('The printer name and fax name must be different. Please choose different names.') 937 self.PrinterNameLineEdit.setToolTip(s) 938 self.FaxNameLineEdit.setToolTip(s) 939 self.printer_name_ok = False 940 self.fax_name_ok = False 941 self.printer_fax_names_same = True 942 943 elif self.fax_name in self.installed_queues: 944 self.FaxNameLineEdit.setToolTip(self.__tr('A fax already exists with this name. Please choose a different name.')) 945 self.fax_name_ok = False 946 947 elif self.printer_fax_names_same: 948 if self.fax_name != self.printer_name: 949 self.printer_fax_names_same = False 950 self.fax_name_ok = True 951 952 self.PrinterNameLineEdit.emit(SIGNAL("textEdited(const QString&)"), 953 self.PrinterNameLineEdit.text()) 954 955 self.setIndicators() 956 self.setAddPrinterButton() 957 958 def SetupPrintGroupBox_clicked(self): 959 if not self.SetupPrintGroupBox.isChecked(): 960 self.SendTestPageCheckBox.setCheckable(False) 961 self.SendTestPageCheckBox.setEnabled(False) 962 else: 963 self.SendTestPageCheckBox.setCheckable(True) 964 self.SendTestPageCheckBox.setEnabled(True) 965 self.setAddPrinterButton() 966 967 def SetupFaxGroupBox_clicked(self): 968 self.setAddPrinterButton() 969 970 971 def setIndicators(self): 972 if self.printer_name_ok: 973 self.PrinterNameLineEdit.setToolTip(str("")) 974 try: 975 self.PrinterNameLineEdit.setStyleSheet("") 976 except AttributeError: 977 pass 978 else: 979 try: 980 self.PrinterNameLineEdit.setStyleSheet("background-color: yellow") 981 except AttributeError: 982 pass 983 984 if self.fax_name_ok: 985 self.FaxNameLineEdit.setToolTip(str("")) 986 try: 987 self.PrinterNameLineEdit.setStyleSheet("") 988 except AttributeError: 989 pass 990 else: 991 try: 992 self.PrinterNameLineEdit.setStyleSheet("background-color: yellow") 993 except AttributeError: 994 pass 995 996 997 def setAddPrinterButton(self): 998 if self.SetupPrintGroupBox.isChecked() or self.SetupFaxGroupBox.isChecked(): 999 self.NextButton.setEnabled((self.print_setup and self.printer_name_ok and self.print_ppd is not None) or 1000 (self.fax_setup and self.fax_name_ok)) 1001 else: 1002 self.NextButton.setEnabled(False) 1003 1004 1005 # 1006 # ADD PRINTER 1007 # 1008 1009 def addPrinter(self): 1010 if self.print_setup: 1011 print_sts = self.setupPrinter() 1012 if print_sts == cups.IPP_FORBIDDEN or print_sts == cups.IPP_NOT_AUTHENTICATED or print_sts == cups.IPP_NOT_AUTHORIZED: 1013 pass # User doesn't have sufficient permissions so ignored. 1014 if print_sts == cups.IPP_OK: 1015 self.flashFirmware() 1016 if self.print_test_page: 1017 self.printTestPage() 1018 1019 if self.fax_setup: 1020 if self.setupFax() == cups.IPP_OK: 1021 self.readwriteFaxInformation(False) 1022 1023 self.close() 1024 1025 1026 # 1027 # Updating firmware download for supported devices. 1028 # 1029 def flashFirmware(self): 1030 if self.mq.get('fw-download', False): 1031 try: 1032 d = device.Device(self.device_uri) 1033 except Error as e: 1034 FailureUI(self, self.__tr("<b>Error opening device. Firmware download is Failed.</b><p>%s (%s)." % (e.msg, e.opt))) 1035 else: 1036 if d.downloadFirmware(): 1037 log.info("Firmware download successful.\n") 1038 else: 1039 FailureUI(self, self.__tr("<b>Firmware download is Failed.</b>")) 1040 d.close() 1041 1042 # 1043 # SETUP PRINTER/FAX 1044 # 1045 1046 def setupPrinter(self): 1047 status = cups.IPP_BAD_REQUEST 1048 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 1049 try: 1050 if not os.path.exists(self.print_ppd[0]): # assume foomatic: or some such 1051 add_prnt_args = (from_unicode_to_str(self.printer_name), self.device_uri, self.print_location, '', self.print_ppd[0], self.print_desc) 1052 else: 1053 add_prnt_args = (from_unicode_to_str(self.printer_name), self.device_uri, self.print_location, self.print_ppd[0], '', self.print_desc) 1054 1055 status, status_str = cups.cups_operation(cups.addPrinter, GUI_MODE, 'qt4', self, *add_prnt_args) 1056 log.debug(device.getSupportedCUPSDevices(['hp'])) 1057 1058 if status != cups.IPP_OK: 1059 QApplication.restoreOverrideCursor() 1060 FailureUI(self, self.__tr("<b>Printer queue setup failed.</b> <p>Error : %s"%status_str)) 1061 else: 1062 # sending Event to add this device in hp-systray 1063 utils.sendEvent(EVENT_CUPS_QUEUES_ADDED,self.device_uri, self.printer_name) 1064 1065 finally: 1066 QApplication.restoreOverrideCursor() 1067 return status 1068 1069 1070 def setupFax(self): 1071 status = cups.IPP_BAD_REQUEST 1072 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 1073 try: 1074 if not os.path.exists(self.fax_ppd): 1075 status, status_str = cups.addPrinter(self.fax_name, 1076 self.fax_uri, self.fax_location, '', self.fax_ppd, self.fax_desc) 1077 else: 1078 status, status_str = cups.addPrinter(self.fax_name, 1079 self.fax_uri, self.fax_location, self.fax_ppd, '', self.fax_desc) 1080 1081 log.debug(device.getSupportedCUPSDevices(['hpfax'])) 1082 1083 if status != cups.IPP_OK: 1084 QApplication.restoreOverrideCursor() 1085 FailureUI(self, self.__tr("<b>Fax queue setup failed.</b><p>Error : %s"%status_str)) 1086 else: 1087 # sending Event to add this device in hp-systray 1088 utils.sendEvent(EVENT_CUPS_QUEUES_ADDED,self.fax_uri, self.fax_name) 1089 1090 finally: 1091 QApplication.restoreOverrideCursor() 1092 1093 return status 1094 1095 1096 def readwriteFaxInformation(self, read=True): 1097 try: 1098 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 1099 1100 d = fax.getFaxDevice(self.fax_uri, disable_dbus=True) 1101 1102 while True: 1103 try: 1104 d.open() 1105 except Error: 1106 error_text = self.__tr("Unable to communicate with the device. Please check the device and try again.") 1107 log.error(to_unicode(error_text)) 1108 if QMessageBox.critical(self, 1109 self.windowTitle(), 1110 error_text, 1111 QMessageBox.Retry | QMessageBox.Default, 1112 QMessageBox.Cancel | QMessageBox.Escape, 1113 QMessageBox.NoButton) == QMessageBox.Cancel: 1114 break 1115 1116 else: 1117 try: 1118 tries = 0 1119 ok = True 1120 1121 while True: 1122 tries += 1 1123 1124 try: 1125 if read: 1126 #self.fax_number = str(d.getPhoneNum()) 1127 #self.fax_name_company = str(d.getStationName()) 1128 self.fax_number = to_unicode(d.getPhoneNum()) 1129 self.fax_name_company = to_unicode(d.getStationName()) 1130 else: 1131 d.setStationName(self.fax_name_company) 1132 d.setPhoneNum(self.fax_number) 1133 1134 except Error: 1135 error_text = self.__tr("<b>Device I/O Error</b><p>Could not communicate with device. Device may be busy.") 1136 log.error(to_unicode(error_text)) 1137 1138 if QMessageBox.critical(self, 1139 self.windowTitle(), 1140 error_text, 1141 QMessageBox.Retry | QMessageBox.Default, 1142 QMessageBox.Cancel | QMessageBox.Escape, 1143 QMessageBox.NoButton) == QMessageBox.Cancel: 1144 break 1145 1146 1147 time.sleep(5) 1148 ok = False 1149 1150 if tries > 12: 1151 break 1152 1153 else: 1154 ok = True 1155 break 1156 1157 finally: 1158 d.close() 1159 1160 if ok and read: 1161 self.FaxNumberLineEdit.setText(self.fax_number) 1162 self.NameCompanyLineEdit.setText(self.fax_name_company) 1163 1164 break 1165 1166 finally: 1167 QApplication.restoreOverrideCursor() 1168 1169 1170 def printTestPage(self): 1171 try: 1172 d = device.Device(self.device_uri) 1173 except Error as e: 1174 FailureUI(self, self.__tr("<b>Device error:</b><p>%s (%s)." % (e.msg, e.opt))) 1175 1176 else: 1177 try: 1178 d.open() 1179 except Error: 1180 FailureUI(self, self.__tr("<b>Unable to print to printer.</b><p>Please check device and try again.")) 1181 else: 1182 if d.isIdleAndNoError(): 1183 d.close() 1184 1185 try: 1186 d.printTestPage(self.printer_name) 1187 except Error as e: 1188 if e.opt == ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE: 1189 FailureUI(self, self.__tr("<b>No CUPS queue found for device.</b><p>Please install the printer in CUPS and try again.")) 1190 else: 1191 FailureUI(self, self.__tr("<b>Printer Error</b><p>An error occured: %s (code=%d)." % (e.msg, e.opt))) 1192 else: 1193 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.")) 1194 d.close() 1195 1196 # 1197 # Remove Page 1198 # 1199 1200 def initRemovePage(self): 1201 pass 1202 1203 1204 def showRemovePage(self): 1205 self.displayPage(PAGE_REMOVE) 1206 self.StepText.setText(self.__tr("Step 1 of 1")) 1207 self.setNextButton(BUTTON_REMOVE) 1208 self.BackButton.setEnabled(False) 1209 self.NextButton.setEnabled(False) 1210 1211 self.RemoveDevicesTableWidget.verticalHeader().hide() 1212 1213 self.installed_printers = device.getSupportedCUPSPrinters(['hp', 'hpfax']) 1214 log.debug(self.installed_printers) 1215 1216 if not self.installed_printers: 1217 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.")) 1218 self.close() 1219 return 1220 1221 self.RemoveDevicesTableWidget.setRowCount(len(self.installed_printers)) 1222 1223 headers = [self.__tr("Select"), self.__tr('Printer (Queue) Name'), self.__tr('Type'), self.__tr('Device URI')] 1224 1225 self.RemoveDevicesTableWidget.setColumnCount(len(headers)) 1226 self.RemoveDevicesTableWidget.setHorizontalHeaderLabels(headers) 1227 flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled 1228 1229 row = 0 1230 for p in self.installed_printers: 1231 widget = QCheckBox(self.RemoveDevicesTableWidget) 1232 widget.stateChanged.connect(self.CheckBox_stateChanged) 1233 self.RemoveDevicesTableWidget.setCellWidget(row, 0, widget) 1234 1235 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \ 1236 device.parseDeviceURI(p.device_uri) 1237 1238 if self.device_uri is not None and self.device_uri == p.device_uri: 1239 widget.setCheckState(Qt.Checked) 1240 1241 i = QTableWidgetItem(str(p.name)) 1242 i.setFlags(flags) 1243 i.setData(Qt.UserRole, p.name) 1244 self.RemoveDevicesTableWidget.setItem(row, 1, i) 1245 1246 if back_end == 'hpfax': 1247 typ = self.__tr("Fax") 1248 else: 1249 typ = self.__tr("Printer") 1250 1251 i = QTableWidgetItem(typ) 1252 i.setFlags(flags) 1253 self.RemoveDevicesTableWidget.setItem(row, 2, i) 1254 1255 i = QTableWidgetItem(str(p.device_uri)) 1256 i.setFlags(flags) 1257 self.RemoveDevicesTableWidget.setItem(row, 3, i) 1258 1259 row += 1 1260 1261 self.RemoveDevicesTableWidget.resizeColumnsToContents() 1262 1263 1264 def CheckBox_stateChanged(self, i): 1265 for row in range(self.RemoveDevicesTableWidget.rowCount()): 1266 widget = self.RemoveDevicesTableWidget.cellWidget(row, 0) 1267 if widget.checkState() == Qt.Checked: 1268 self.NextButton.setEnabled(True) 1269 break 1270 else: 1271 self.NextButton.setEnabled(False) 1272 1273 1274 # 1275 # Misc 1276 # 1277 1278 def NextButton_clicked(self): 1279 p = self.StackedWidget.currentIndex() 1280 if p == PAGE_DISCOVERY: 1281 self.manual = self.ManualGroupBox.isChecked() 1282 self.param = to_unicode(self.ManualParamLineEdit.text()) 1283 self.jd_port = self.JetDirectSpinBox.value() 1284 self.search = to_unicode(self.SearchLineEdit.text()) 1285 self.device_desc = value_int(self.DeviceTypeComboBox.itemData(self.DeviceTypeComboBox.currentIndex()))[0] 1286 self.discovery_method = self.NetworkDiscoveryMethodComboBox.currentIndex() 1287 1288 if self.WirelessButton.isChecked(): 1289 dlg = WifiSetupDialog(self, device_uri=None, standalone=False) 1290 dlg.exec_() 1291 1292 if dlg.success == SUCCESS_CONNECTED: 1293 self.manual = True 1294 self.param = dlg.hn 1295 self.bus = 'net' 1296 if not self.WirelessButton.isChecked(): 1297 self.showDevicesPage() 1298 1299 elif p == PAGE_DEVICES: 1300 row = self.DevicesTableWidget.currentRow() 1301 self.device_uri = self.DevicesTableWidget.item(row, 0).device_uri 1302 self.mq = device.queryModelByURI(self.device_uri) 1303 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.device_uri) 1304 self.model = models.normalizeModelName(model).lower() 1305 self.showAddPrinterPage() 1306 1307 elif p == PAGE_ADD_PRINTER: 1308 self.print_test_page = self.SendTestPageCheckBox.isChecked() 1309 self.print_setup = self.SetupPrintGroupBox.isChecked() 1310 self.fax_setup = self.SetupFaxGroupBox.isChecked() 1311 self.print_location = from_unicode_to_str(to_unicode(self.PrinterLocationLineEdit.text())) 1312 self.print_desc = from_unicode_to_str(to_unicode(self.PrinterDescriptionLineEdit.text())) 1313 self.fax_desc = from_unicode_to_str(to_unicode(self.FaxDescriptionLineEdit.text())) 1314 self.fax_location = from_unicode_to_str(to_unicode(self.FaxLocationLineEdit.text())) 1315 self.fax_name_company = to_unicode(self.NameCompanyLineEdit.text()) 1316 self.fax_number = to_unicode(self.FaxNumberLineEdit.text()) 1317 self.addPrinter() 1318 1319 elif p == PAGE_REMOVE: 1320 for row in range(self.RemoveDevicesTableWidget.rowCount()): 1321 widget = self.RemoveDevicesTableWidget.cellWidget(row, 0) 1322 if widget.checkState() == Qt.Checked: 1323 item = self.RemoveDevicesTableWidget.item(row, 1) 1324 printer = to_unicode(value_str(item.data(Qt.UserRole))) 1325 uri = device.getDeviceURIByPrinterName(printer) 1326 log.debug("Removing printer: %s" % printer) 1327 status, status_str = cups.cups_operation(cups.delPrinter, GUI_MODE, 'qt4', self, printer) 1328 1329 if status != cups.IPP_OK: 1330 FailureUI(self, self.__tr("<b>Unable to delete '%s' queue. </b><p>Error : %s"%(printer,status_str))) 1331 if status == cups.IPP_FORBIDDEN or status == cups.IPP_NOT_AUTHENTICATED or status == cups.IPP_NOT_AUTHORIZED: 1332 break 1333 else: 1334 # sending Event to add this device in hp-systray 1335 utils.sendEvent(EVENT_CUPS_QUEUES_REMOVED, uri, printer) 1336 1337 self.close() 1338 1339 else: 1340 log.error("Invalid page!") # shouldn't happen! 1341 1342 1343 def BackButton_clicked(self): 1344 p = self.StackedWidget.currentIndex() 1345 if p == PAGE_DEVICES: 1346 self.devices = {} 1347 self.showDiscoveryPage() 1348 1349 elif p == PAGE_ADD_PRINTER: 1350 self.showDevicesPage() 1351 1352 else: 1353 log.error("Invalid page!") # shouldn't happen! 1354 1355 1356 def CancelButton_clicked(self): 1357 self.close() 1358 1359 1360 def displayPage(self, page): 1361 self.StackedWidget.setCurrentIndex(page) 1362 self.updateStepText(page) 1363 1364 1365 def setNextButton(self, typ=BUTTON_FINISH): 1366 if typ == BUTTON_ADD_PRINTER: 1367 self.NextButton.setText(self.__tr("Add Printer")) 1368 elif typ == BUTTON_NEXT: 1369 self.NextButton.setText(self.__tr("Next >")) 1370 elif typ == BUTTON_FINISH: 1371 self.NextButton.setText(self.__tr("Finish")) 1372 elif typ == BUTTON_REMOVE: 1373 self.NextButton.setText(self.__tr("Remove")) 1374 1375 1376 def updateStepText(self, p): 1377 self.StepText.setText(self.__tr("Step %s of %s"%(p+1, self.max_page+1))) #Python 3.2 1378 1379 1380 def __tr(self,s,c = None): 1381 return qApp.translate("SetupDialog",s,c) 1382 1383 1384