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