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