1# -*- coding: utf-8 -*-
2#
3# (c) Copyright 2001-2015 HP 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# Author: Don Welch, Yashwant Kumar Sahu
20#
21
22# Local
23from base.g import *
24from base import utils
25from base.sixext import  to_unicode
26from prnt import cups
27from .jobstoragemixin import JobStorageMixin
28
29# Qt
30from qt import *
31from .scrollview import ScrollView
32
33# Std Lib
34import os.path
35import os
36
37
38class RangeValidator(QValidator):
39    def __init__(self, parent=None, name=None):
40        QValidator.__init__(self, parent, name)
41
42    def validate(self, input, pos):
43        for x in to_unicode(input)[pos-1:]:
44            if x not in '0123456789,- ':
45                return QValidator.Invalid, pos
46
47        return QValidator.Acceptable, pos
48
49
50class OptionComboBox(QComboBox):
51    def __init__(self, rw, parent, name, group, option, choices, default, typ=cups.PPD_UI_PICKONE, other=None):
52        QComboBox.__init__(self, rw, parent, name)
53        self.group = group
54        self.option = option
55        self.choices = choices
56        self.default = default
57        self.typ = typ
58        self.other = other
59
60    def setDefaultPushbutton(self, pushbutton):
61        self.pushbutton = pushbutton
62
63    def setOther(self, other):
64        self.other = other
65
66
67class OptionSpinBox(QSpinBox):
68    def __init__(self,  parent, name, group, option, default):
69        QSpinBox.__init__(self, parent, name)
70        self.group = group
71        self.option = option
72        self.default = default
73
74    def setDefaultPushbutton(self, pushbutton):
75        self.pushbutton = pushbutton
76
77
78class OptionButtonGroup(QButtonGroup):
79    def __init__(self,  parent, name, group, option, default):
80        QButtonGroup.__init__(self, parent, name)
81        self.group = group
82        self.option = option
83        self.default = default
84
85    def setDefaultPushbutton(self, pushbutton):
86        self.pushbutton = pushbutton
87
88
89class DefaultPushButton(QPushButton):
90    def __init__(self,  parent, name, group, option, choices, default, control, typ):
91        QPushButton.__init__(self, parent, name)
92        self.group = group
93        self.option = option
94        self.default = default
95        self.control = control
96        self.typ = typ
97        self.choices = choices
98
99
100
101class ScrollPrintSettingsView(ScrollView):
102    utils.mixin(JobStorageMixin)
103
104    def __init__(self, service, parent=None, name=None, fl=0):
105        ScrollView.__init__(self, service, parent, name, fl)
106
107        self.initJobStorage(True)
108
109
110
111    def fillControls(self):
112        QApplication.setOverrideCursor(QApplication.waitCursor)
113
114        ScrollView.fillControls(self)
115
116        self.loading = True
117        cups.resetOptions()
118        cups.openPPD(self.cur_printer)
119        cur_outputmode = ""
120
121        #if 1:
122        try:
123            if 1:
124            #try:
125                current_options = dict(cups.getOptions())
126
127                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
128                    self.addGroupHeading("basic", self.__tr("Basic"))
129                    log.debug("Group: Basic")
130
131                    # Basic
132                        # PageSize (in PPD section)
133                        # orientation-requested
134                        # sides
135                        # outputorder
136                        # Collate
137
138
139                    current = current_options.get('orientation-requested', '3')
140
141                    self.addItem("basic", "orientation-requested", self.__tr("Page Orientation"),
142                        cups.PPD_UI_PICKONE, current,
143                        [('3', self.__tr('Portrait')),
144                         ('4', self.__tr('Landscape')),
145                         ('5', self.__tr('Reverse landscape')),
146                         ('6', self.__tr('Reverse portrait'))], '3')
147
148                    log.debug("Option: orientation-requested")
149                    log.debug("Current value: %s" % current)
150
151                    duplexer = self.cur_device.dq.get('duplexer', 0)
152                    log.debug("Duplexer = %d" % duplexer)
153
154                    if duplexer:
155                        current = current_options.get('sides', 'one-sided')
156                        self.addItem("basic", "sides",
157                            self.__tr("Duplex (Print on both sides of the page)"),
158                            cups.PPD_UI_PICKONE, current,
159                            [('one-sided',self.__tr('Single sided')),
160                             ('two-sided-long-edge', self.__tr('Two sided (long edge)')),
161                             ('two-sided-short-edge', self.__tr('Two sided (short edge)'))], 'one-sided')
162
163                        log.debug("Option: sides")
164                        log.debug("Current value: %s" % current)
165
166                    current = current_options.get('outputorder', 'normal')
167
168                    self.addItem("basic", "outputorder",
169                        self.__tr("Output Order (Print last page first)"),
170                        cups.PPD_UI_PICKONE, current,
171                        [('normal', self.__tr('Normal (Print first page first)')),
172                         ('reverse', self.__tr('Reversed (Print last page first)'))], 'normal')
173
174                    log.debug("Option: outputorder")
175                    log.debug("Current value: %s" % current)
176
177                    current = utils.to_bool(current_options.get('Collate', '0'))
178
179                    self.addItem("basic", "Collate",
180                        self.__tr("Collate (Group together multiple copies)"),
181                        cups.PPD_UI_BOOLEAN, current,
182                        [], 0)
183
184                    log.debug("Option: Collate")
185                    log.debug("Current value: %s" % current)
186
187                groups = cups.getGroupList()
188
189                for g in groups:
190                    log.debug("Group: %s" % repr(g))
191
192                    if 'jobretention' in g.lower():
193                        log.debug("HPJobRetention skipped.")
194                        continue
195
196                    text, num_subgroups = cups.getGroup(g)
197                    read_only = 'install' in g.lower()
198
199                    try:
200                        text = text.decode('utf-8')
201                    except UnicodeDecodeError:
202                        pass
203
204                    if g.lower() == 'printoutmode':
205                        text = self.__tr("Quality")
206
207                    self.addGroupHeading(g, text, read_only)
208
209                    log.debug("  Text: %s" % repr(text))
210                    log.debug("Num subgroups: %d" % num_subgroups)
211
212                    options = cups.getOptionList(g)
213
214                    for o in options:
215                        log.debug("  Option: %s" % repr(o))
216
217                        if 'pageregion' in o.lower():
218                            log.debug("Page Region skipped.")
219                            continue
220
221
222
223                        option_text, defchoice, conflicted, ui  = cups.getOption(g, o)
224
225                        try:
226                            option_text = option_text.decode('utf-8')
227                        except UnicodeDecodeError:
228                            pass
229
230                        if o.lower() == 'quality':
231                            option_text = self.__tr("Quality")
232
233                        log.debug("    Text: %s" % repr(option_text))
234                        log.debug("    Defchoice: %s" % repr(defchoice))
235
236                        choices = cups.getChoiceList(g, o)
237
238                        value = None
239                        choice_data = []
240                        for c in choices:
241                            log.debug("    Choice: %s" % repr(c))
242
243                            # TODO: Add custom paper size controls
244                            if 'pagesize' in o.lower() and 'custom' in c.lower():
245                                log.debug("Skipped.")
246                                continue
247
248                            choice_text, marked = cups.getChoice(g, o, c)
249
250                            try:
251                                choice_text = choice_text.decode('utf-8')
252                            except UnicodeDecodeError:
253                                pass
254
255                            log.debug("      Text: %s" % repr(choice_text))
256
257                            if marked:
258                                value = c
259
260                            choice_data.append((c, choice_text))
261
262                        if o.lower() == 'outputmode':
263                            if value is not None:
264                                cur_outputmode = value
265                            else:
266                                cur_outputmode = defchoice
267
268                        self.addItem(g, o, option_text, ui, value, choice_data, defchoice, read_only)
269
270##                        if 'pagesize' in o.lower(): # and 'custom' in c.lower():
271##                            current = 0.0
272##                            width_widget = self.addItem("custom", "custom-width", self.__tr("Custom Paper Width"), cups.UI_UNITS_SPINNER,
273##                                current, (0.0, 0.0), 0.0)
274##
275##                            current = 0.0
276##                            height_widget = self.addItem("custom", "custom-height", self.__tr("Custom Paper Height"), cups.UI_UNITS_SPINNER,
277##                                current, (0.0, 0.0), 0.0)
278##
279##                            if value.lower() == 'custom':
280##                                pass
281
282                # N-Up
283                    # number-up
284                    # number-up-layout
285                    # page-border
286
287                self.addGroupHeading("nup",
288                    self.__tr("N-Up (Multiple document pages per printed page)"))
289
290                log.debug("Group: N-Up")
291
292                current = current_options.get('number-up', '1')
293
294                self.addItem("nup", "number-up", self.__tr("Pages per Sheet"),
295                    cups.PPD_UI_PICKONE, current,
296                    [('1', self.__tr('1 page per sheet')),
297                     ('2', self.__tr('2 pages per sheet')),
298                     ('4', self.__tr('4 pages per sheet'))], '1')
299
300                log.debug("  Option: number-up")
301                log.debug("  Current value: %s" % current)
302
303                current = current_options.get('number-up-layout', 'lrtb')
304
305                self.addItem("nup", "number-up-layout", self.__tr("Layout"),
306                    cups.PPD_UI_PICKONE, current,
307                    [('btlr', self.__tr('Bottom to top, left to right')),
308                     ('btrl', self.__tr('Bottom to top, right to left')),
309                     ('lrbt', self.__tr('Left to right, bottom to top')),
310                     ('lrtb', self.__tr('Left to right, top to bottom')),
311                     ('rlbt', self.__tr('Right to left, bottom to top')),
312                     ('rltb', self.__tr('Right to left, top to bottom')),
313                     ('tblr', self.__tr('Top to bottom, left to right')),
314                     ('tbrl', self.__tr('Top to bottom, right to left')) ], 'lrtb')
315
316                log.debug("  Option: number-up-layout")
317                log.debug("  Current value: %s" % current)
318
319                current = current_options.get('page-border', 'none')
320
321                self.addItem("nup", "page-border",
322                    self.__tr("Printed Border Around Each Page"),
323                    cups.PPD_UI_PICKONE, current,
324                    [('double', self.__tr("Two thin borders")),
325                     ("double-thick", self.__tr("Two thick borders")),
326                     ("none", self.__tr("No border")),
327                     ("single", self.__tr("One thin border")),
328                     ("single-thick", self.__tr("One thick border"))], 'none')
329
330                log.debug("  Option: page-border")
331                log.debug("  Current value: %s" % current)
332
333                # Adjustment
334                    # brightness
335                    # gamma
336
337                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
338                    self.addGroupHeading("adjustment", self.__tr("Printout Appearance"))
339
340                    current = int(current_options.get('brightness', 100))
341
342                    log.debug("  Option: brightness")
343                    log.debug("  Current value: %s" % current)
344
345                    self.addItem("adjustment", "brightness", self.__tr("Brightness"),
346                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")
347
348                    current = int(current_options.get('gamma', 1000))
349
350                    log.debug("  Option: gamma")
351                    log.debug("  Current value: %s" % current)
352
353                    self.addItem("adjustment", "gamma", self.__tr("Gamma"), cups.UI_SPINNER, current,
354                        (1, 10000), 1000)
355
356                # Margins (pts)
357                    # page-left
358                    # page-right
359                    # page-top
360                    # page-bottom
361
362##                if 0:
363##                    # TODO: cupsPPDPageSize() fails on LaserJets. How do we get margins in this case? Defaults?
364##                    # PPD file for LJs has a HWMargin entry...
365##                    page, page_width, page_len, left, bottom, right, top = cups.getPPDPageSize()
366##
367##                    right = page_width - right
368##                    top = page_len - top
369##
370##                    self.addGroupHeading("margins", self.__tr("Margins"))
371##                    current_top = current_options.get('page-top', 0) # pts
372##                    current_bottom = current_options.get('page-bottom', 0) # pts
373##                    current_left = current_options.get('page-left', 0) # pts
374##                    current_right = current_options.get('page-right', 0) # pts
375##
376##                    log.debug("  Option: page-top")
377##                    log.debug("  Current value: %s" % current_top)
378##
379##                    self.addItem("margins", "page-top", self.__tr("Top margin"),
380##                        cups.UI_UNITS_SPINNER, current_top,
381##                        (0, page_len), top)
382##
383##                    self.addItem("margins", "page-bottom", self.__tr("Bottom margin"),
384##                        cups.UI_UNITS_SPINNER, current_bottom,
385##                        (0, page_len), bottom)
386##
387##                    self.addItem("margins", "page-left", self.__tr("Right margin"),
388##                        cups.UI_UNITS_SPINNER, current_left,
389##                        (0, page_width), left)
390##
391##                    self.addItem("margins", "page-right", self.__tr("Left margin"),
392##                        cups.UI_UNITS_SPINNER, current_right,
393##                        (0, page_width), right)
394
395                # Image Printing
396                    # position
397                    # natural-scaling
398                    # saturation
399                    # hue
400
401                self.addGroupHeading("image", self.__tr("Image Printing"))
402
403                current = utils.to_bool(current_options.get('fitplot', 'false'))
404
405                self.addItem("image", "fitplot",
406                    self.__tr("Fit to Page"),
407                    cups.PPD_UI_BOOLEAN, current,
408                    [], 0)
409
410
411                current = current_options.get('position', 'center')
412
413                self.addItem("image", "position", self.__tr("Position on Page"),
414                    cups.PPD_UI_PICKONE, current,
415                    [('center', self.__tr('Centered')),
416                     ('top', self.__tr('Top')),
417                     ('left', self.__tr('Left')),
418                     ('right', self.__tr('Right')),
419                     ('top-left', self.__tr('Top left')),
420                     ('top-right', self.__tr('Top right')),
421                     ('bottom', self.__tr('Bottom')),
422                     ('bottom-left', self.__tr('Bottom left')),
423                     ('bottom-right', self.__tr('Bottom right'))], 'center')
424
425                log.debug("  Option: position")
426                log.debug("  Current value: %s" % current)
427
428                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
429                    current = int(current_options.get('saturation', 100))
430
431                    log.debug("  Option: saturation")
432                    log.debug("  Current value: %s" % current)
433
434                    self.addItem("image", "saturation", self.__tr("Saturation"),
435                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")
436
437                    current = int(current_options.get('hue', 0))
438
439                    log.debug("  Option: hue")
440                    log.debug("  Current value: %s" % current)
441
442                    self.addItem("image", "hue", self.__tr("Hue (color shift/rotation)"),
443                        cups.UI_SPINNER, current,
444                        (-100, 100), 0)
445
446                current = int(current_options.get('natural-scaling', 100))
447
448                log.debug("  Option: natural-scaling")
449                log.debug("  Current value: %s" % current)
450
451                self.addItem("image", "natural-scaling",
452                    self.__tr('"Natural" Scaling (relative to image)'),
453                    cups.UI_SPINNER, current, (1, 800), 100, suffix=" %")
454
455                current = int(current_options.get('scaling', 100))
456
457                log.debug("  Option: scaling")
458                log.debug("  Current value: %s" % current)
459
460                self.addItem("image", "scaling", self.__tr("Scaling (relative to page)"),
461                    cups.UI_SPINNER, current,
462                    (1, 800), 100, suffix=" %")
463
464                # Misc
465                    # PrettyPrint
466                    # job-sheets
467                    # mirror
468
469                self.addGroupHeading("misc", self.__tr("Miscellaneous"))
470
471                log.debug("Group: Misc")
472
473                current = utils.to_bool(current_options.get('prettyprint', '0'))
474
475                self.addItem("misc", "prettyprint",
476                    self.__tr('"Pretty Print" Text Documents (Add headers and formatting)'),
477                    cups.PPD_UI_BOOLEAN, current, [], 0)
478
479                log.debug("  Option: prettyprint")
480                log.debug("  Current value: %s" % current)
481
482                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
483                    current = current_options.get('job-sheets', 'none').split(',')
484
485                    try:
486                        start = current[0]
487                    except IndexError:
488                        start = 'none'
489
490                    try:
491                        end = current[1]
492                    except IndexError:
493                        end = 'none'
494
495                    # TODO: Look for locally installed banner pages beyond the default CUPS ones?
496                    self.addItem("misc", "job-sheets", self.__tr("Banner Pages"), cups.UI_BANNER_JOB_SHEETS,
497                        (start, end),
498                        [("none", self.__tr("No banner page")),
499                         ('classified', self.__tr("Classified")),
500                         ('confidential', self.__tr("Confidential")),
501                         ('secret', self.__tr("Secret")),
502                         ('standard', self.__tr("Standard")),
503                         ('topsecret', self.__tr("Top secret")),
504                         ('unclassified', self.__tr("Unclassified"))], ('none', 'none'))
505
506                    log.debug("  Option: job-sheets")
507                    log.debug("  Current value: %s,%s" % (start, end))
508
509                current = utils.to_bool(current_options.get('mirror', '0'))
510
511                self.addItem("misc", "mirror", self.__tr('Mirror Printing'),
512                    cups.PPD_UI_BOOLEAN, current, [], 0)
513
514                log.debug("  Option: mirror")
515                log.debug("  Current value: %s" % current)
516
517                #Summary
518                    #color input
519                    #quality
520                quality_attr_name = "OutputModeDPI"
521                cur_outputmode_dpi = cups.findPPDAttribute(quality_attr_name, cur_outputmode)
522                if cur_outputmode_dpi is not None:
523                    log.debug("Adding Group: Summary outputmode is : %s" % cur_outputmode)
524                    log.debug("Adding Group: Summary outputmode dpi is : %s" % str (cur_outputmode_dpi))
525                    self.addGroupHeading("summry", self.__tr("Summary"))
526                    self.addItem("summry", "colorinput", self.__tr('Color Input / Black Render'),
527                        cups.UI_INFO, cur_outputmode_dpi, [], 0)
528                    self.addItem("summry", "quality", self.__tr('Print Quality'),
529                        cups.UI_INFO, cur_outputmode, [], 0)
530
531                self.job_storage_avail = 0 #self.cur_device.mq['job-storage'] == JOB_STORAGE_ENABLE
532
533                #print current_options
534
535                if self.job_storage_avail:
536                    self.addGroupHeading("jobstorage", self.__tr("Job Storage and Secure Printing"))
537                    self.addJobStorage(current_options)
538
539
540            #except Exception, e:
541                #log.exception()
542            #    pass
543
544        finally:
545            cups.closePPD()
546            self.loading = False
547            QApplication.restoreOverrideCursor()
548
549    def ComboBox_indexChanged(self, currentItem):
550        sender = self.sender()
551        currentItem = to_unicode(currentItem)
552        # Checking for summary control
553        labelPQValaue = getattr(self, 'PQValueLabel', None)
554        labelPQColorInput = getattr(self, 'PQColorInputLabel', None)
555        # When output mode combo item is changed, we need to update the summary information
556        if currentItem is not None and sender.option == 'OutputMode' and labelPQValaue is not None and labelPQColorInput is not None:
557            # Setting output mode
558            self.PQValueLabel.setText(currentItem)
559
560            # Getting DPI custom attributefrom the PPD
561            # Setting color input
562            quality_attr_name = "OutputModeDPI"
563            cups.openPPD(self.cur_printer)
564            outputmode_dpi = cups.findPPDAttribute(quality_attr_name, currentItem)
565            log.debug("Outputmode changed, setting outputmode_dpi: %s" % outputmode_dpi)
566            cups.closePPD()
567            self.PQColorInputLabel.setText(outputmode_dpi)
568
569            log.debug("Outputmode changed, setting value outputmode: %s" % currentItem)
570
571    def optionComboBox_activated(self, a):
572        a = to_unicode(a)
573        sender = self.sender()
574        choice = None
575
576        if sender.typ == cups.UI_BANNER_JOB_SHEETS:
577            start, end = None, None
578            for c, t in sender.choices:
579                if t == a:
580                    start = c
581                    break
582
583            for c, t in sender.other.choices:
584                if t == sender.other.currentText():
585                    end = c
586                    break
587
588            if sender.option == 'end':
589                start, end = end, start
590
591            if start is not None and \
592                end is not None and \
593                start.lower() == sender.default[0].lower() and \
594                end.lower() == sender.default[1].lower():
595                    self.removePrinterOption('job-sheets')
596                    sender.pushbutton.setEnabled(False)
597            else:
598                sender.pushbutton.setEnabled(True)
599
600                if start is not None and \
601                    end is not None:
602
603                    self.setPrinterOption('job-sheets', ','.join([start, end]))
604
605        else:
606            choice = None
607            for c, t in sender.choices:
608                if t == a:
609                    choice = c
610                    break
611
612            if choice is not None and choice.lower() == sender.default.lower():
613                self.removePrinterOption(sender.option)
614                sender.pushbutton.setEnabled(False)
615            else:
616                sender.pushbutton.setEnabled(True)
617
618                if choice is not None:
619                    self.setPrinterOption(sender.option, choice)
620
621            self.linkPrintoutModeAndQuality(sender.option, choice)
622
623
624    def linkPrintoutModeAndQuality(self, option, choice):
625        if option.lower() == 'quality' and \
626            choice is not None:
627
628            try:
629                c = self.items['o:PrintoutMode'].control
630            except KeyError:
631                return
632            else:
633                if c is not None:
634                    if choice.lower() == 'fromprintoutmode':
635                        # from printoutmode selected
636                        # determine printoutmode option combo enable state
637                        c.setEnabled(True)
638                        QToolTip.remove(c)
639                        a = to_unicode(c.currentText())
640
641                        # determine printoutmode default button state
642                        link_choice = None
643                        for x, t in c.choices:
644                            if t == a:
645                                link_choice = x
646                                break
647
648                        if link_choice is not None and \
649                            link_choice.lower() == c.default.lower():
650
651                            c.pushbutton.setEnabled(False)
652                        else:
653                            c.pushbutton.setEnabled(True)
654
655                    else: # fromprintoutmode not selected, disable printoutmode
656                        c.setEnabled(False)
657                        QToolTip.add(c, self.__tr("""Set Quality to "Controlled by 'Printout Mode'" to enable."""))
658                        c.pushbutton.setEnabled(False)
659
660
661
662    def optionSpinBox_valueChanged(self, i):
663        sender = self.sender()
664
665        if i == sender.default:
666            self.removePrinterOption(sender.option)
667            sender.pushbutton.setEnabled(False)
668        else:
669            sender.pushbutton.setEnabled(True)
670            self.setPrinterOption(sender.option, str(i))
671
672
673    def optionButtonGroup_clicked(self, b):
674        sender = self.sender()
675        b = int(b)
676
677        if b == sender.default:
678            self.removePrinterOption(sender.option)
679            sender.pushbutton.setEnabled(False)
680        else:
681            sender.pushbutton.setEnabled(True)
682
683            if b:
684                self.setPrinterOption(sender.option, "true")
685            else:
686                self.setPrinterOption(sender.option, "false")
687
688
689
690    def defaultPushButton_clicked(self):
691        sender = self.sender()
692        sender.setEnabled(False)
693
694        if sender.typ == cups.PPD_UI_BOOLEAN:
695            if sender.default:
696                sender.control.setButton(1)
697            else:
698                sender.control.setButton(0)
699
700            self.removePrinterOption(sender.option)
701
702        elif sender.typ == cups.PPD_UI_PICKONE:
703            choice, text = None, None
704
705            for c, t in sender.choices:
706                if c == sender.default:
707                    choice = c
708                    text = t
709                    break
710
711            if choice is not None:
712                self.removePrinterOption(sender.option)
713                sender.control.setCurrentText(text)
714
715                self.linkPrintoutModeAndQuality(sender.option, choice)
716
717        elif sender.typ == cups.UI_SPINNER:
718            sender.control.setValue(sender.default)
719            self.removePrinterOption(sender.option)
720
721        elif sender.typ == cups.UI_BANNER_JOB_SHEETS:
722            start, end, start_text, end_text = None, None, None, None
723            for c, t in sender.choices:
724                if c == sender.default[0]:
725                    start = c
726                    start_text = t
727
728                if c == sender.default[1]:
729                    end = c
730                    end_text = t
731
732            if start is not None:
733                sender.control[0].setCurrentText(start_text)
734
735            if end is not None:
736                sender.control[1].setCurrentText(end_text)
737
738            self.removePrinterOption('job-sheets')
739
740
741    def setPrinterOption(self, option, value):
742        cups.openPPD(self.cur_printer)
743
744        try:
745            cups.addOption("%s=%s" % (option, value))
746            cups.setOptions()
747        finally:
748            cups.closePPD()
749
750    def removePrinterOption(self, option):
751        cups.openPPD(self.cur_printer)
752
753        try:
754            cups.removeOption(option)
755            cups.setOptions()
756        finally:
757            cups.closePPD()
758
759
760    def addItem(self, group, option, text, typ, value, choices, default, read_only=False, suffix=""):
761        widget, control = None, None
762
763        if typ == cups.PPD_UI_BOOLEAN: # () On (*) Off widget
764            widget = self.getWidget()
765            layout = QGridLayout(widget, 1, 1, 5, 10, "layout")
766            default = int(utils.to_bool(str(default)))
767            value = int(utils.to_bool(str(value)))
768
769            textLabel1 = QLabel(widget, "textLabel1")
770            layout.addWidget(textLabel1, 0, 0)
771
772            buttonGroup = OptionButtonGroup(widget, "buttonGroup", group, option, default)
773            buttonGroup.setLineWidth(0)
774            buttonGroup.setColumnLayout(0,Qt.Vertical)
775            buttonGroup.layout().setSpacing(1)
776            buttonGroup.layout().setMargin(5)
777            buttonGroupLayout = QHBoxLayout(buttonGroup.layout())
778            buttonGroupLayout.setAlignment(Qt.AlignTop)
779
780            defaultPushButton = DefaultPushButton(widget,"defaultPushButton", group, option,
781                choices, default, buttonGroup, typ)
782
783            buttonGroup.setDefaultPushbutton(defaultPushButton)
784
785            layout.addWidget(defaultPushButton, 0, 3)
786
787            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
788            layout.addItem(spacer1, 0, 1)
789
790            onRadioButton = QRadioButton(buttonGroup,"onRadioButton")
791            buttonGroup.insert(onRadioButton, 1)
792            buttonGroupLayout.addWidget(onRadioButton)
793
794            offRadioButton = QRadioButton(buttonGroup,"offRadioButton")
795            buttonGroup.insert(offRadioButton, 0)
796            buttonGroupLayout.addWidget(offRadioButton)
797
798            layout.addWidget(buttonGroup, 0, 2)
799
800            textLabel1.setText(text)
801            onRadioButton.setText(self.__tr("On"))
802            offRadioButton.setText(self.__tr("Off"))
803
804            if value == default:
805                defaultPushButton.setEnabled(False)
806
807            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
808            self.connect(buttonGroup, SIGNAL("clicked(int)"), self.optionButtonGroup_clicked)
809
810            x = self.__tr('Off')
811            if default:
812                x = self.__tr('On')
813
814            if value:
815                buttonGroup.setButton(1)
816            else:
817                buttonGroup.setButton(0)
818
819            if read_only:
820                onRadioButton.setEnabled(False)
821                offRadioButton.setEnabled(False)
822                defaultPushButton.setEnabled(False)
823            else:
824                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "%1".').arg(x))
825
826            defaultPushButton.setText("Default")
827
828        elif typ == cups.PPD_UI_PICKONE: # Combo box widget
829            widget = self.getWidget()
830
831            layout1 = QHBoxLayout(widget,5,10,"layout1")
832
833            textLabel1 = QLabel(widget,"textLabel1")
834            layout1.addWidget(textLabel1)
835
836            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
837            layout1.addItem(spacer1)
838
839            optionComboBox = OptionComboBox(0, widget, "optionComboBox", group, option, choices, default)
840            layout1.addWidget(optionComboBox)
841
842            defaultPushButton = DefaultPushButton(widget,"defaultPushButton", group, option,
843                choices, default, optionComboBox, typ)
844
845            optionComboBox.setDefaultPushbutton(defaultPushButton)
846
847            layout1.addWidget(defaultPushButton)
848
849            textLabel1.setText(text)
850            defaultPushButton.setText("Default")
851
852            x, y = None, None
853            for c, t in choices:
854                d = c.lower()
855                if value is not None and d == value.lower():
856                    x = t
857
858                if d == default.lower():
859                    y = t
860
861                optionComboBox.insertItem(t)
862
863            if x is not None:
864                optionComboBox.setCurrentText(x)
865
866            if value is not None and value.lower() == default.lower():
867                defaultPushButton.setEnabled(False)
868
869            self.linkPrintoutModeAndQuality(option, value)
870
871            if read_only:
872                optionComboBox.setEnabled(False)
873                defaultPushButton.setEnabled(False)
874            elif y is not None:
875                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "%1".').arg(y))
876
877            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
878            self.connect(optionComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
879            self.connect(optionComboBox, SIGNAL("activated(const QString &)"), self.ComboBox_indexChanged)
880
881            control = optionComboBox
882
883        elif typ == cups.UI_SPINNER: # Spinner widget
884            widget = self.getWidget()
885
886            layout1 = QHBoxLayout(widget,5,10, "layout1")
887
888            textLabel1 = QLabel(widget, "textLabel1")
889            layout1.addWidget(textLabel1)
890
891            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
892            layout1.addItem(spacer1)
893
894            optionSpinBox = OptionSpinBox(widget,"optionSpinBox", group, option, default)
895            layout1.addWidget(optionSpinBox)
896
897            defaultPushButton = DefaultPushButton(widget, "defaultPushButton", group, option, choices,
898                default, optionSpinBox, typ)
899
900            optionSpinBox.setDefaultPushbutton(defaultPushButton)
901
902            layout1.addWidget(defaultPushButton)
903
904            min, max = choices
905            optionSpinBox.setMinValue(min)
906            optionSpinBox.setMaxValue(max)
907            optionSpinBox.setValue(value)
908
909            if suffix:
910                optionSpinBox.setSuffix(suffix)
911
912            textLabel1.setText(text)
913            defaultPushButton.setText("Default")
914
915            self.connect(optionSpinBox, SIGNAL("valueChanged(int)"), self.optionSpinBox_valueChanged)
916            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
917
918            if value == default:
919                defaultPushButton.setEnabled(False)
920
921            if read_only:
922                self.optionSpinBox.setEnabled(False)
923                self.defaultPushButton.setEnabled()
924            else:
925                QToolTip.add(defaultPushButton,
926                    self.__tr('Set to default value of "%1".').arg(default))
927
928        elif typ == cups.UI_BANNER_JOB_SHEETS:  # Job sheets widget
929            widget = self.getWidget()
930
931            layout1 = QGridLayout(widget,1,1,5,10,"layout1")
932
933            startComboBox = OptionComboBox(0, widget, "startComboBox", group,
934                "start", choices, default, typ)
935
936            layout1.addWidget(startComboBox,0,3)
937
938            startTextLabel = QLabel(widget,"startTextLabel")
939            layout1.addWidget(startTextLabel,0,2)
940
941            endTextLabel = QLabel(widget,"endTextLabel")
942            layout1.addWidget(endTextLabel,0,4)
943
944            endComboBox = OptionComboBox(0, widget, "endComboBox", group, "end", choices,
945                default, typ, startComboBox)
946
947            layout1.addWidget(endComboBox,0,5)
948
949            startComboBox.setOther(endComboBox)
950
951            defaultPushButton = DefaultPushButton(widget, "defaultPushButton", group, option, choices,
952                default, (startComboBox, endComboBox), typ)
953
954            layout1.addWidget(defaultPushButton,0,6)
955
956            startComboBox.setDefaultPushbutton(defaultPushButton)
957            endComboBox.setDefaultPushbutton(defaultPushButton)
958
959            textLabel1 = QLabel(widget,"textLabel1")
960            layout1.addWidget(textLabel1,0,0)
961
962            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
963            layout1.addItem(spacer1,0,1)
964
965            textLabel1.setText(text)
966            defaultPushButton.setText("Default")
967
968            startTextLabel.setText(self.__tr("Start:"))
969            endTextLabel.setText(self.__tr("End:"))
970
971            s, e, y, z = None, None, None, None
972            for c, t in choices:
973                d = c.lower()
974                if value is not None:
975                    if d == value[0].lower():
976                        s = t
977
978                    if d == value[1].lower():
979                        e = t
980
981                if d == default[0].lower():
982                    y = t
983
984                if d == default[1].lower():
985                    z = t
986
987                startComboBox.insertItem(t)
988                endComboBox.insertItem(t)
989
990            if s is not None:
991                startComboBox.setCurrentText(s)
992
993            if e is not None:
994                endComboBox.setCurrentText(e)
995
996            if value is not None and \
997                value[0].lower() == default[0].lower() and \
998                value[1].lower() == default[1].lower():
999
1000                defaultPushButton.setEnabled(False)
1001
1002            if y is not None and z is not None:
1003                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "Start: %1, End: %2".').arg(y).arg(z))
1004
1005            self.connect(startComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
1006            self.connect(endComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
1007            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
1008
1009        elif typ == cups.PPD_UI_PICKMANY:
1010            log.error("Unrecognized type: pickmany")
1011
1012        elif typ == cups.UI_UNITS_SPINNER:
1013            widget = self.getWidget()
1014
1015            layout1 = QHBoxLayout(widget,5,10,"layout1")
1016
1017            textLabel1 = QLabel(widget,"textLabel1")
1018            layout1.addWidget(textLabel1)
1019
1020            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
1021            layout1.addItem(spacer1)
1022
1023            lineEdit1 = QLineEdit(widget,"lineEdit1")
1024            layout1.addWidget(lineEdit1)
1025
1026            comboBox1 = QComboBox(0,widget,"comboBox1")
1027            layout1.addWidget(comboBox1)
1028
1029            defaultPushButton = QPushButton(widget,"defaultPushButton")
1030            layout1.addWidget(defaultPushButton)
1031
1032            textLabel1.setText(text)
1033            defaultPushButton.setText("Default")
1034
1035        elif typ == cups.UI_INFO:
1036            widget = self.getWidget()
1037
1038            layout1 = QHBoxLayout(widget,5,10,"layout1")
1039
1040            textPropName = QLabel(widget,"textPropName")
1041            layout1.addWidget(textPropName)
1042            textPropName.setText(text)
1043
1044            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
1045            layout1.addItem(spacer1)
1046
1047            if text == 'Print Quality':
1048                self.PQValueLabel = QLabel(widget,"textPropValue")
1049                layout1.addWidget(self.PQValueLabel)
1050                self.PQValueLabel.setText(value)
1051            elif text == 'Color Input / Black Render':
1052                self.PQColorInputLabel = QLabel(widget,"textPropValue")
1053                layout1.addWidget(self.PQColorInputLabel)
1054                self.PQColorInputLabel.setText(value)
1055            else:
1056                textPropValue = QLabel(widget,"textPropValue")
1057                layout1.addWidget(textPropValue)
1058                textPropValue.setText(value)
1059
1060        else:
1061            log.error("Invalid UI value: %s/%s" % (group, option))
1062
1063        if widget is not None:
1064            self.addWidget(widget, "o:"+option, control)
1065            return widget
1066
1067
1068
1069    def __tr(self,s,c = None):
1070        return qApp.translate("ScrollPrintSettingsView",s,c)
1071