1 # -*- coding: utf-8 -*-
3 # (c) Copyright 2001-2009 Hewlett-Packard Development Company, L.P.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # Author: Don Welch, Goutam Korra, Naga Samrat Chowdary Narla,
32 from base import device, utils, models, pkit
34 from installer import core_install
35 from ui_utils import load_pixmap
42 # This can fail on Python < 2.3 due to the datetime module
44 log.warning("Fax setup disabled - Python 2.3+ required.")
48 from setupform_base import SetupForm_base
49 from setupsettings import SetupSettings
50 from setupmanualfind import SetupManualFind
53 if os.path.exists('/etc/init.d/cups'):
54 return '/etc/init.d/cups restart'
56 elif os.path.exists('/etc/init.d/cupsys'):
57 return '/etc/init.d/cupsys restart'
60 return 'killall -HUP cupsd'
63 class DeviceListViewItem(QListViewItem):
64 def __init__(self, parent, device_uri, mq, c1='', c2='', c3='', c4=''):
65 QListViewItem.__init__(self, parent, c1, c2, c3, c4)
66 self.device_uri = device_uri
70 class PPDListViewItem(QListViewItem):
71 def __init__(self, parent, ppd_file, c1=''):
72 QListViewItem.__init__(self, parent, ppd_file, c1)
73 self.ppd_file = ppd_file
76 class PrinterNameValidator(QValidator):
77 def __init__(self, parent=None, name=None):
78 QValidator.__init__(self, parent, name)
80 def validate(self, input, pos):
81 input = unicode(input)
84 return QValidator.Acceptable, pos
86 elif input[pos-1] in u"""~`!@#$%^&*()-=+[]{}()\\/,.<>?'\";:| """:
87 return QValidator.Invalid, pos
89 # TODO: How to determine if unicode char is "printable" and acceptable
91 #elif input != utils.printable(input):
92 # return QValidator.Invalid, pos
95 return QValidator.Acceptable, pos
99 class PhoneNumValidator(QValidator):
100 def __init__(self, parent=None, name=None):
101 QValidator.__init__(self, parent, name)
103 def validate(self, input, pos):
104 input = unicode(input)
107 return QValidator.Acceptable, pos
109 elif input[pos-1] not in u'0123456789-(+) ':
110 return QValidator.Invalid, pos
113 return QValidator.Acceptable, pos
117 class SetupForm(SetupForm_base):
118 def __init__(self, bus, param, jd_port=1, parent=None, name=None, modal=0, fl=0):
119 SetupForm_base.__init__(self, parent, name, modal, fl)
121 self.start_page = self.ConnectionPage
122 self.first_page = True
128 self.start_page = self.ProbedDevicesPage
130 if not prop.par_build:
131 self.parRadioButton.setEnabled(False)
133 if not prop.net_build:
134 self.netRadioButton.setEnabled(False)
136 if not prop.par_build and not prop.net_build:
138 self.start_page = self.ProbedDevicesPage
141 self.jd_port = jd_port
145 device_uri, sane_uri, fax_uri = device.makeURI(self.param, self.jd_port)
148 self.device_uri = device_uri
149 self.start_page = self.PPDPage
152 self.FailureUI(self.__tr("<b>Device not found.</b> <p>Please make sure your printer is properly connected and powered-on."))
154 self.setIcon(load_pixmap('hp_logo', '128x128'))
156 self.connectionTypeButtonGroup.setButton(0)
159 self.prev_page = None
160 self.probe_pat = re.compile(r'(.*?)\s"(.*?)"\s"(.*?)"\s"(.*?)"', re.IGNORECASE)
161 self.printer_name = ''
169 self.printer_name_ok = True
170 self.fax_name_ok = True
173 self.printer_fax_names_same = False
174 self.fax_name_company = ''
175 self.fax_location = ''
177 self.print_test_page = True
178 self.printerNameLineEdit.setValidator(PrinterNameValidator(self.printerNameLineEdit))
179 self.faxNameLineEdit.setValidator(PrinterNameValidator(self.faxNameLineEdit))
180 self.faxNumberLineEdit.setValidator(PhoneNumValidator(self.faxNumberLineEdit))
181 self.setTitleFont(QFont("Helvetica", 16))
182 self.setBackEnabled(self.FinishedPage, False)
183 self.bg = self.printerNameLineEdit.paletteBackgroundColor()
184 self.setHelpEnabled(self.ConnectionPage, False)
185 self.setHelpEnabled(self.ProbedDevicesPage, False)
186 self.setHelpEnabled(self.PPDPage, False)
187 self.setHelpEnabled(self.PrinterNamePage, False)
188 self.setHelpEnabled(self.FinishedPage, False)
190 self.faxNameLineEdit.setMaxLength(50)
191 self.printerNameLineEdit.setMaxLength(50)
193 QToolTip.add(self.searchFiltersPushButton2,
194 self.__tr('Current: Filter: [%2] Search: "%3" TTL: %4 Timeout: %5s').arg(','.join(self.filter)).arg(self.search or '').arg(self.ttl).arg(self.timeout))
196 cups.setPasswordCallback(showPasswordUI)
199 def showPage(self, page):
203 page = self.start_page
204 self.first_page = False
206 log.debug("%s %s %s" % ("*"*20, "showPage(%s)" % page.name(), "*"*20))
209 log.debug("%s --> %s" % (self.prev_page.name(), page.name()))
210 except AttributeError:
211 log.debug("--> %s" % page.name())
213 if page is self.ConnectionPage: # start --> ConnectionPage
216 elif page is self.ProbedDevicesPage:
217 # ConnectionPage --> ProbedDevicesPage/EnterIPPage/DeviceNotFoundPage
218 devices_found = self.updateProbedDevicesPage()
221 elif page is self.PPDPage: # ProbedDevicesPage --> PPDPage
223 device_uri, sane_uri, fax_uri = device.makeURI(self.param, self.jd_port)
226 self.device_uri = device_uri
228 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
229 device.parseDeviceURI(self.device_uri)
232 self.mq = device.queryModelByURI(self.device_uri)
234 norm_model = models.normalizeModelName(model).lower()
236 core = core_install.CoreInstall()
237 core.set_plugin_version()
238 plugin = self.mq.get('plugin', PLUGIN_NONE)
239 plugin_reason = self.mq.get('plugin-reason', PLUGIN_REASON_NONE)
240 if plugin > PLUGIN_NONE and core.check_for_plugin() != PLUGIN_INSTALLED:
241 ok, sudo_ok = pkit.run_plugin_command(plugin == PLUGIN_REQUIRED, plugin_reason)
243 self.FailureUI(self.__tr("<b>Unable to find an appropriate su/sudo utility to run hp-plugin.</b><p>Install kdesu, gnomesu, or gksu.</p>"))
245 if not ok or core.check_for_plugin() != PLUGIN_INSTALLED:
246 if plugin == PLUGIN_REQUIRED:
247 self.FailureUI(self.__tr("<b>The printer you are trying to setup requires a binary driver plug-in and it failed to install.</b><p>Please check your internet connection and try again.</p><p>Visit <u>http://hplipopensource.com</u> for more information.</p>"))
250 self.WarningUI(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."))
254 elif page is self.PrinterNamePage:
255 self.setDefaultPrinterName()
257 if fax_import_ok and prop.fax_build and \
258 self.mq.get('fax-type', FAX_TYPE_NONE) not in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED):
260 self.faxCheckBox.setEnabled(True)
261 self.faxCheckBox.setEnabled(True)
262 self.faxNameLineEdit.setEnabled(True)
263 self.faxNumberLineEdit.setEnabled(True)
264 self.faxNameCoLineEdit.setEnabled(True)
265 self.faxLocationLineEdit.setEnabled(True)
266 self.faxDescriptionLineEdit.setEnabled(True)
267 self.faxInfoGroupBox.setEnabled(True)
268 self.setup_fax = True
269 self.setDefaultFaxName()
270 self.readwriteFaxInformation(True)
273 self.setup_fax = False
274 self.fax_name_ok = True
275 self.defaultFaxNamePushButton.setEnabled(False)
276 self.faxCheckBox.setEnabled(False)
277 self.faxNameLineEdit.setEnabled(False)
278 self.faxNumberLineEdit.setEnabled(False)
279 self.faxNameCoLineEdit.setEnabled(False)
280 self.faxLocationLineEdit.setEnabled(False)
281 self.faxDescriptionLineEdit.setEnabled(False)
282 self.faxInfoGroupBox.setEnabled(False)
284 elif page is self.FinishedPage:
285 self.lineEdit1.setText(self.printer_name)
286 self.lineEdit2.setText(self.location)
287 self.lineEdit3.setText(self.desc)
288 self.lineEdit4.setText(self.ppd_file)
290 #log.debug("Restarting CUPS...")
291 #status, output = utils.run(restart_cups())
292 #log.debug("Restart CUPS returned: exit=%d output=%s" % (status, output))
298 self.readwriteFaxInformation(False)
300 self.lineEdit5.setText(self.fax_number)
301 self.lineEdit6.setText(self.fax_name)
302 self.lineEdit7.setText(self.fax_name_company)
303 self.lineEdit8.setText(self.fax_location)
304 self.lineEdit9.setText(self.fax_desc)
306 self.faxGroupBox.setEnabled(True)
309 self.faxGroupBox.setEnabled(False)
311 self.setFinishEnabled(self.FinishedPage, True)
313 if orig_page != page:
315 log.debug("%s --> %s" % (self.prev_page.name(), page.name()))
316 except AttributeError:
317 log.debug("--> %s" % page.name())
319 self.prev_page = page
320 QWizard.showPage(self, page)
322 if page is self.ProbedDevicesPage: # ConnectionPage --> ProbedDevicesPage/EnterIPPage/DeviceNotFoundPage
323 if not devices_found:
324 self.FailureUI(self.__tr("<b>No devices found.</b><p>Please make sure your printer is properly connected and powered-on."))
328 # CONNECTION TYPE PAGE
331 def connectionTypeButtonGroup_clicked(self,a0):
344 def searchFiltersPushButton2_clicked(self):
348 # FILTERS SEARCH SETTINGS
351 def settingsDlg(self):
352 dlg = SetupSettings(self.bus, self.filter, self.search, self.ttl, self.timeout, self)
353 if dlg.exec_loop() == QDialog.Accepted:
354 #self.filter = [x.lower().strip() for x in dlg.filter.split(',')]
355 self.filter = dlg.filter
356 self.search = dlg.search
358 self.timeout = dlg.timeout
360 t = self.__tr('Current Settings: Filter: [%2] Search: "%3" TTL: %4 Timeout: %5s').arg(','.join(self.filter)).arg(self.search or '').arg(self.ttl).arg(self.timeout)
362 QToolTip.add(self.searchFiltersPushButton2, t)
363 QToolTip.add(self.searchFiltersPushButton, t)
369 # PROBED DEVICES PAGE
372 def updateProbedDevicesPage(self, devices=None, param=''):
373 QApplication.setOverrideCursor(QApplication.waitCursor)
375 if self.bus == 'net':
376 io_str = self.__tr("network")
378 elif self.bus == 'usb':
379 io_str = self.__tr("USB bus")
381 elif self.bus == 'par':
382 io_str = self.__tr("parallel port")
384 QToolTip.add(self.searchFiltersPushButton, self.__tr('Current Settings: Filter: [%2] Search: "%3" TTL: %4 Timeout: %5s').arg(','.join(self.filter)).arg(self.search or '').arg(self.ttl).arg(self.timeout))
386 log.debug("Updating probed devices list...")
389 self.probedDevicesListView.clear()
391 while self.probedDevicesListView.columns():
392 self.probedDevicesListView.removeColumn(0)
394 self.probedDevicesListView.addColumn(self.__tr("Model"))
396 if self.bus == 'usb':
397 self.probedDevicesListView.addColumn(self.__tr("Serial No."))
399 elif self.bus == 'net':
400 self.probedDevicesListView.addColumn(self.__tr("IP Address"))
401 self.probedDevicesListView.addColumn(self.__tr("Host Name"))
403 elif self.bus == 'par':
404 self.probedDevicesListView.addColumn(self.__tr("Device"))
406 self.probedDevicesListView.addColumn(self.__tr("Device URI"))
409 FILTER_MAP = {'print' : None,
413 'pcard': 'pcard-type',
419 if prop.fax_build and prop.scan_build:
420 for f in self.filter:
422 filter_dict[FILTER_MAP[f]] = (operator.gt, 0)
424 filter_dict[f] = (operator.gt, 0)
426 filter_dict['scan-type'] = (operator.ge, SCAN_TYPE_NONE)
428 devices = device.probeDevices([self.bus], self.timeout, self.ttl, filter_dict, self.search, net_search='slp')
430 self.probeHeadingTextLabel.setText(self.__tr("%1 device(s) found on the %1:").arg(len(devices)).arg(io_str))
433 if self.bus == 'net':
434 self.probeHeadingTextLabel.setText(self.__tr("%1 device(s) found on the %1 at address %2:").arg(len(devices)).arg(io_str).arg(param))
436 elif self.bus == 'usb':
437 self.probeHeadingTextLabel.setText(self.__tr("%1 device(s) found on the %1 at ID %2:").arg(len(devices)).arg(io_str).arg(param))
439 elif self.bus == 'par':
440 self.probeHeadingTextLabel.setText(self.__tr("%1 device(s) found on the %1 device node ID %2:").arg(len(devices)).arg(io_str).arg(param))
447 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(d)
450 model_ui = models.normalizeModelUIName(model)
452 if self.bus == 'usb':
453 i = DeviceListViewItem(self.probedDevicesListView, d, mq, model_ui, serial, d)
455 elif self.bus == 'net':
456 i = DeviceListViewItem(self.probedDevicesListView, d, mq, model_ui, host, devices[d][2], d)
458 elif self.bus == 'par':
459 i = DeviceListViewItem(self.probedDevicesListView, d, mq, model_ui, dev_file, d)
463 i = self.probedDevicesListView.firstChild()
464 self.probedDevicesListView.setCurrentItem(i)
465 self.probedDevicesListView.setSelected(i, True)
466 item = self.probedDevicesListView.currentItem()
467 self.device_uri = item.device_uri
468 self.updateModelQuery(item)
469 self.setNextEnabled(self.ProbedDevicesPage, True)
470 log.debug(self.device_uri)
473 self.setNextEnabled(self.ProbedDevicesPage, False)
474 QApplication.restoreOverrideCursor()
477 QApplication.restoreOverrideCursor()
480 def updateModelQuery(self, item):
482 item.mq = device.queryModelByURI(self.device_uri)
489 def probedDevicesListView_currentChanged(self, item):
490 self.device_uri = item.device_uri
491 self.updateModelQuery(item)
492 log.debug(self.device_uri)
494 def probeUpdatePushButton_clicked(self):
495 self.updateProbedDevicesPage()
497 def searchFiltersPushButton_clicked(self):
498 if self.settingsDlg():
499 self.updateProbedDevicesPage()
501 def manualFindPushButton_clicked(self):
502 dlg = SetupManualFind(self.bus, self)
503 if dlg.exec_loop() == QDialog.Accepted:
504 QApplication.setOverrideCursor(QApplication.waitCursor)
506 cups_uri, sane_uri, fax_uri = device.makeURI(dlg.param)
509 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(cups_uri)
511 if self.bus == 'net':
513 name = socket.gethostbyaddr(host)[0]
514 except socket.herror:
517 QApplication.restoreOverrideCursor()
518 self.updateProbedDevicesPage({cups_uri: (model, model, name)}, dlg.param)
520 QApplication.restoreOverrideCursor()
521 self.updateProbedDevicesPage([], dlg.param)
527 def updatePPDPage(self, ppds=None):
528 QApplication.setOverrideCursor(QApplication.waitCursor)
530 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.device_uri)
532 self.FailureUI(self.__tr("<b>Device not found or invalid HPLIP device.</b><p>If you specified a USB ID, IP address, or other parameter, please re-check it and try again."))
536 if ppds is None or not ppds:
537 ppds = cups.getSystemPPDs()
541 default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
542 stripped_model = cups.stripModel2(models.normalizeModelName(model).lower())
545 #Check if common ppd name is already given in models.dat(This is needed because in case of devices having more than one derivatives
546 #will have diffrent model name strings in device ID, because of which we don't get the common ppd name for search)
548 ppd_name = self.mq.get('ppd-name',0)
551 self.ppd = cups.getPPDFile2(stripped_model, ppds)
553 self.ppd = cups.getPPDFile2(ppd_name, ppds)
556 self.ppdListView.clear()
558 if self.ppd is not None:
559 #for ppd in self.ppd_dict:
560 PPDListViewItem(self.ppdListView, self.ppd[0], self.ppd[1])
562 # i = self.ppdListView.firstChild()
563 # self.ppdListView.setCurrentItem(i)
564 # self.ppdListView.setSelected(i, True)
565 # self.ppd_file = self.ppdListView.currentItem().ppd_file
566 self.ppd_file = self.ppd[0]
567 log.debug(self.ppd_file)
570 self.FailureUI(self.__tr('<b>PPD not file found.</b><p>An appropriate PPD file could not be found. Please check your HPLIP install, use <i>Select Other...</i>, or download one from linuxprinting.org.'))
572 QApplication.restoreOverrideCursor()
575 def ppdListView_currentChanged(self,a0):
576 self.ppd_file = a0.ppd_file
577 log.debug(self.ppd_file)
580 def otherPPDPushButton_clicked(self):
581 ppd_dir = sys_conf.get('dirs', 'ppd')
582 ppd_file = unicode(QFileDialog.getOpenFileName(ppd_dir, "PPD Files (*.ppd *.ppd.gz);;All Files (*)", self, "open file dialog", "Choose a PPD file"))
584 if ppd_file and os.path.exists(ppd_file):
585 self.updatePPDPage({ppd_file: cups.getPPDDescription(ppd_file)})
589 def ppdDefaultsPushButton_clicked(self):
594 # PRINTER/FAX INFORMATION PAGE
597 def setDefaultPrinterName(self):
598 self.installed_print_devices = device.getSupportedCUPSDevices(['hp'])
599 #self.installed_print_devices = device.getSupportedCUPSDevices('*')
600 log.debug(self.installed_print_devices)
602 self.installed_queues = [p.name for p in cups.getPrinters()]
604 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.device_uri)
605 default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
607 printer_name = default_model
609 installed_printer_names = device.getSupportedCUPSPrinterNames(['hp'])
610 # Check for duplicate names
611 if (self.device_uri in self.installed_print_devices and printer_name in self.installed_print_devices[self.device_uri]) \
612 or (printer_name in installed_printer_names):
615 t = printer_name + "_%d" % i
616 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]):
617 printer_name += "_%d" % i
621 self.printer_name_ok = True
622 self.printerNameLineEdit.setText(printer_name)
623 log.debug(printer_name)
624 self.printerNameLineEdit.setPaletteBackgroundColor(self.bg)
625 self.defaultPrinterNamePushButton.setEnabled(False)
626 self.printer_name = printer_name
629 def setEditErrors(self):
630 if self.printer_name_ok:
631 self.printerNameLineEdit.setPaletteBackgroundColor(self.bg)
632 self.printer_name_ok = True
635 self.setNextEnabled(self.PrinterNamePage, True)
637 QToolTip.remove(self.printerNameLineEdit)
640 self.printerNameLineEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))
641 self.setNextEnabled(self.PrinterNamePage, False)
644 self.fax_name_ok = True
645 self.faxNameLineEdit.setPaletteBackgroundColor(self.bg)
647 if self.printer_name_ok:
648 self.setNextEnabled(self.PrinterNamePage, True)
650 QToolTip.remove(self.faxNameLineEdit)
653 self.faxNameLineEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))
654 self.setNextEnabled(self.PrinterNamePage, False)
657 def printerNameLineEdit_textChanged(self,a0):
658 self.printer_name = unicode(a0)
659 self.defaultPrinterNamePushButton.setEnabled(True)
661 self.printer_name_ok = True
663 if not self.printer_name:
664 QToolTip.add(self.printerNameLineEdit, self.__tr('You must enter a name for the printer.'))
665 self.printer_name_ok = False
667 elif self.fax_name == self.printer_name:
668 s = self.__tr('The printer name and fax name must be different. Please choose different names.')
669 QToolTip.add(self.faxNameLineEdit, s)
670 QToolTip.add(self.printerNameLineEdit, s)
671 self.fax_name_ok = False
672 self.printer_name_ok = False
673 self.printer_fax_names_same = True
675 elif self.printer_name in self.installed_queues:
676 QToolTip.add(self.printerNameLineEdit,
677 self.__tr('A printer already exists with this name. Please choose a different name.'))
678 self.printer_name_ok = False
680 elif self.printer_fax_names_same:
681 if self.fax_name != self.printer_name:
682 self.printer_fax_names_same = False
683 self.printer_name_ok = True
685 self.faxNameLineEdit.emit(SIGNAL("textChanged(const QString&)"),
686 (self.faxNameLineEdit.text(),))
691 def printerLocationLineEdit_textChanged(self, a0):
692 self.location = unicode(a0)
694 def printerDescriptionLineEdit_textChanged(self,a0):
695 self.desc = unicode(a0)
697 def faxLocationLineEdit_textChanged(self,a0):
698 self.fax_location = unicode(a0)
700 def faxDescriptionLineEdit_textChanged(self,a0):
701 self.fax_desc = unicode(a0)
703 def defaultPrinterNamePushButton_clicked(self):
704 self.setDefaultPrinterName()
705 self.defaultPrinterNamePushButton.setEnabled(False)
707 def setDefaultFaxName(self):
708 self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
709 log.debug(self.installed_fax_devices)
711 self.fax_uri = self.device_uri.replace('hp:', 'hpfax:')
713 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(self.fax_uri)
714 default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
716 fax_name = default_model + "_fax"
717 installed_fax_names = device.getSupportedCUPSPrinterNames(['hpfax'])
719 # Check for duplicate names
720 if (self.fax_uri in self.installed_fax_devices and fax_name in self.installed_fax_devices[self.fax_uri]) \
721 or (fax_name in installed_fax_names):
722 #if fax_name in self.installed_queues or fax_name == self.printer_name:
725 t = fax_name + "_%d" % i
726 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]):
727 fax_name += "_%d" % i
731 self.fax_name_ok = True
732 self.faxNameLineEdit.setText(fax_name)
733 self.faxNameLineEdit.setPaletteBackgroundColor(self.bg)
734 self.defaultFaxNamePushButton.setEnabled(False)
735 self.fax_name = fax_name
736 #self.fax_name_error = False
738 def faxNameLineEdit_textChanged(self, a0):
739 self.fax_name = unicode(a0)
740 self.defaultFaxNamePushButton.setEnabled(True)
742 self.fax_name_ok = True
744 if not self.fax_name:
745 QToolTip.add(self.faxNameLineEdit, self.__tr('You must enter a fax name.'))
746 self.fax_name_ok = False
748 elif self.fax_name == self.printer_name:
749 s = self.__tr('The printer name and fax name must be different. Please choose different names.')
750 QToolTip.add(self.faxNameLineEdit, s)
751 QToolTip.add(self.printerNameLineEdit, s)
752 self.printer_name_ok = False
753 self.fax_name_ok = False
754 self.printer_fax_names_same = True
756 elif self.fax_name in self.installed_queues:
757 QToolTip.add(self.faxNameLineEdit,
758 self.__tr('A fax already exists with this name. Please choose a different name.'))
759 self.fax_name_ok = False
761 elif self.printer_fax_names_same:
762 if self.fax_name != self.printer_name:
763 self.printer_fax_names_same = False
764 self.fax_name_ok = True
766 self.printerNameLineEdit.emit(SIGNAL("textChanged(const QString&)"),
767 (self.printerNameLineEdit.text(),))
772 def faxNumberLineEdit_textChanged(self, a0):
773 self.fax_number = unicode(a0)
775 def faxNameCoLineEdit_textChanged(self, a0):
776 self.fax_name_company = unicode(a0)
778 def faxCheckBox_clicked(self):
781 def faxCheckBox_toggled(self, a0):
782 self.setup_fax = bool(a0)
784 if not self.setup_fax and not self.fax_name_ok:
785 self.setDefaultFaxName()
787 def printTestPageCheckBox_toggled(self, a0):
788 self.print_test_page = bool(a0)
790 def defaultFaxNamePushButton_clicked(self):
791 self.setDefaultFaxName()
792 self.defaultFaxNamePushButton.setEnabled(False)
794 def readwriteFaxInformation(self, read=True):
796 QApplication.setOverrideCursor(QApplication.waitCursor)
798 d = fax.getFaxDevice(self.fax_uri, disable_dbus=True)
804 error_text = self.__tr("Unable to communicate with the device. Please check the device and try again.")
805 log.error(unicode(error_text))
806 if QMessageBox.critical(self,
809 QMessageBox.Retry | QMessageBox.Default,
810 QMessageBox.Cancel | QMessageBox.Escape,
811 QMessageBox.NoButton) == QMessageBox.Cancel:
824 self.fax_number = unicode(d.getPhoneNum())
825 self.fax_name_company = unicode(d.getStationName())
827 d.setStationName(self.fax_name_company)
828 d.setPhoneNum(self.fax_number)
831 error_text = self.__tr("<b>Device I/O Error</b><p>Could not communicate with device. Device may be busy.")
832 log.error(unicode(error_text))
834 if QMessageBox.critical(self,
837 QMessageBox.Retry | QMessageBox.Default,
838 QMessageBox.Cancel | QMessageBox.Escape,
839 QMessageBox.NoButton) == QMessageBox.Cancel:
857 self.faxNumberLineEdit.setText(self.fax_number)
858 self.faxNameCoLineEdit.setText(self.fax_name_company)
863 QApplication.restoreOverrideCursor()
869 def setupPrinter(self):
870 QApplication.setOverrideCursor(QApplication.waitCursor)
872 cups.setPasswordPrompt("You do not have permission to add a printer.")
873 #if self.ppd_file.startswith("foomatic:"):
874 if not os.path.exists(self.ppd_file): # assume foomatic: or some such
875 status, status_str = cups.addPrinter(self.printer_name.encode('utf8'), self.device_uri,
876 self.location, '', self.ppd_file, self.desc)
878 status, status_str = cups.addPrinter(self.printer_name.encode('utf8'), self.device_uri,
879 self.location, self.ppd_file, '', self.desc)
881 log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
882 self.installed_print_devices = device.getSupportedCUPSDevices(['hp'])
884 log.debug(self.installed_print_devices)
886 if self.device_uri not in self.installed_print_devices or \
887 self.printer_name not in self.installed_print_devices[self.device_uri]:
889 self.FailureUI(self.__tr("<b>Printer queue setup failed.</b><p>Please restart CUPS and try again."))
892 #service.sendEvent(self.hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=self.device_uri)
895 QApplication.restoreOverrideCursor()
898 QApplication.setOverrideCursor(QApplication.waitCursor)
900 if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
901 fax_ppd_name = "HP-Fax3-hplip" # Fixed width (2528 pixels) and 300dpi rendering
903 if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
904 fax_ppd_name = "HP-Fax2-hplip" # Fixed width (2528 pixels) and 300dpi rendering
906 if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
907 fax_ppd_name = "HP-Fax4-hplip" # Fixed width (1728 pixels) and 200dpi rendering
910 fax_ppd_name = "HP-Fax-hplip" # Standard
915 log.debug("Searching for fax file %s..." % fax_ppd_name)
917 ppd_dir = sys_conf.get('dirs', 'ppd')
918 for f in utils.walkFiles(ppd_dir, pattern="HP-Fax*.ppd*", abs_paths=True):
922 if f.find(fax_ppd_name) >= 0:
924 log.debug("Found PDD file: %s" % fax_ppd)
925 log.debug("Nickname: %s" % cups.getPPDDescription(fax_ppd))
928 QApplication.restoreOverrideCursor()
929 log.error("Fax PPD file not found.")
931 if QMessageBox.warning(self, self.__tr("Unable to find HP fax PPD file."),
932 self.__tr("The PPD file (%1.ppd) needed to setup the fax queue was not found.").arg(fax_ppd_name),
933 self.__tr("Browse to file..."), # button 0
934 self.__tr("Quit") # button 1
938 ppd_dir = sys_conf.get('dirs', 'ppd')
939 fax_ppd = unicode(QFileDialog.getOpenFileName(ppd_dir,
940 "HP Fax PPD Files (*.ppd *.ppd.gz);;All Files (*)", self,
941 "open file dialog", "Choose the fax PPD file"))
943 if not fax_ppd: # user hit cancel
946 if os.path.exists(fax_ppd):
947 n = cups.getPPDDescription(fax_ppd)
951 self.FailureUI(self.__tr("<b>Incorrect fax PPD file.</b><p>The fax PPD file must have a nickname of '%1', not '%1'.").arg(nick).arg(n))
953 self.FailureUI(self.__tr("<b>File not found.</b><p>hp-setup cannot find the file %1").arg(fax_ppd))
958 cups.setPasswordPrompt("You do not have permission to add a fax device.")
959 if not os.path.exists(fax_ppd):
960 status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
961 self.fax_uri, self.fax_location, '', fax_ppd, self.fax_desc)
963 status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
964 self.fax_uri, self.fax_location, fax_ppd, '', self.fax_desc)
966 log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
967 self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
969 log.debug(self.installed_fax_devices)
971 if self.fax_uri not in self.installed_fax_devices or \
972 self.fax_name not in self.installed_fax_devices[self.fax_uri]:
974 self.FailureUI(self.__tr("<b>Fax queue setup failed.</b><p>Please restart CUPS and try again."))
978 #service.sendEvent(self.hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=self.fax_uri)
980 QApplication.restoreOverrideCursor()
983 if self.print_test_page:
985 d = device.Device(self.device_uri)
987 self.FailureUI(self.__tr("<b>Device error:</b><p>%s (%s)." % (e.msg, e.opt)))
993 self.FailureUI(self.__tr("<b>Unable to print to printer.</b><p>Please check device and try again."))
995 if d.isIdleAndNoError():
999 d.printTestPage(self.printer_name)
1001 if e.opt == ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE:
1002 self.FailureUI(self.__tr("<b>No CUPS queue found for device.</b><p>Please install the printer in CUPS and try again."))
1004 self.FailureUI(self.__tr("<b>Printer Error</b><p>An error occured: %s (code=%d)." % (e.msg, e.opt)))
1006 self.FailureUI(self.__tr("<b>Printer Error.</b><p>Printer is busy, offline, or in an error state. Please check the device and try again."))
1010 QWizard.accept(self)
1014 QWizard.reject(self)
1016 def FailureUI(self, error_text):
1017 log.error(unicode(error_text).replace("<b>", "").replace("</b>", "").replace("<p>", " "))
1018 QMessageBox.critical(self,
1022 QMessageBox.NoButton,
1023 QMessageBox.NoButton)
1025 def WarningUI(self, error_text):
1026 QMessageBox.warning(self,
1030 QMessageBox.NoButton,
1031 QMessageBox.NoButton)
1033 def __tr(self, s, c=None):
1034 return qApp.translate("SetupForm", s, c)
1038 class PasswordDialog(QDialog):
1039 def __init__(self,prompt, parent=None, name=None, modal=0, fl=0):
1040 QDialog.__init__(self,parent,name,modal,fl)
1041 self.prompt = prompt
1044 self.setName("PasswordDialog")
1046 passwordDlg_baseLayout = QGridLayout(self,1,1,11,6,"passwordDlg_baseLayout")
1048 self.promptTextLabel = QLabel(self,"promptTextLabel")
1049 passwordDlg_baseLayout.addMultiCellWidget(self.promptTextLabel,0,0,0,1)
1051 self.usernameTextLabel = QLabel(self,"usernameTextLabel")
1052 passwordDlg_baseLayout.addMultiCellWidget(self.usernameTextLabel,1,1,0,1)
1054 self.usernameLineEdit = QLineEdit(self,"usernameLineEdit")
1055 self.usernameLineEdit.setEchoMode(QLineEdit.Normal)
1056 passwordDlg_baseLayout.addMultiCellWidget(self.usernameLineEdit,1,1,1,2)
1058 self.passwordTextLabel = QLabel(self,"passwordTextLabel")
1059 passwordDlg_baseLayout.addMultiCellWidget(self.passwordTextLabel,2,2,0,1)
1061 self.passwordLineEdit = QLineEdit(self,"passwordLineEdit")
1062 self.passwordLineEdit.setEchoMode(QLineEdit.Password)
1063 passwordDlg_baseLayout.addMultiCellWidget(self.passwordLineEdit,2,2,1,2)
1065 self.okPushButton = QPushButton(self,"okPushButton")
1066 passwordDlg_baseLayout.addWidget(self.okPushButton,3,2)
1068 self.languageChange()
1070 self.resize(QSize(420,163).expandedTo(self.minimumSizeHint()))
1071 self.clearWState(Qt.WState_Polished)
1073 self.connect(self.okPushButton,SIGNAL("clicked()"),self.accept)
1074 self.connect(self.passwordLineEdit,SIGNAL("returnPressed()"),self.accept)
1076 def setDefaultUsername(self, defUser, allowUsernameEdit = True):
1077 self.usernameLineEdit.setText(defUser)
1078 if not allowUsernameEdit:
1079 self.usernameLineEdit.setReadOnly(True)
1080 self.usernameLineEdit.setPaletteBackgroundColor(QColor("lightgray"))
1082 def getUsername(self):
1083 return unicode(self.usernameLineEdit.text())
1085 def getPassword(self):
1086 return unicode(self.passwordLineEdit.text())
1088 def languageChange(self):
1089 self.setCaption(self.__tr("HP Device Manager - Enter Username/Password"))
1090 self.promptTextLabel.setText(self.__tr(self.prompt))
1091 self.usernameTextLabel.setText(self.__tr("Username"))
1092 self.passwordTextLabel.setText(self.__tr("Password"))
1093 self.okPushButton.setText(self.__tr("OK"))
1095 def __tr(self,s,c = None):
1096 return qApp.translate("PasswordDialog",s,c)
1099 def showPasswordUI(prompt, userName=None, allowUsernameEdit=True):
1101 dlg = PasswordDialog(prompt, None)
1103 if userName != None:
1104 dlg.setDefaultUsername(userName, allowUsernameEdit)
1106 if dlg.exec_loop() == QDialog.Accepted:
1107 return (dlg.getUsername(), dlg.getPassword())