~mimose/+junk/hplip-3.16.11

« back to all changes in this revision

Viewing changes to ui5/printsettingstoolbox.py

  • Committer: guoyalong
  • Date: 2017-09-20 10:13:05 UTC
  • Revision ID: guoyalong@kylinos.cn-20170920101305-82zaolzpv1qghz29
Modified debian/control & debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
# Authors: Don Welch, Yashwant Kumar Sahu, Sanjay Kumar Sharma
 
20
#
 
21
 
 
22
# Std Lib
 
23
import sys
 
24
 
 
25
# Local
 
26
from base.g import *
 
27
from base import utils
 
28
from prnt import cups
 
29
from base.codes import *
 
30
from .ui_utils import *
 
31
from base.sixext import PY3
 
32
from base.sixext import  to_unicode
 
33
 
 
34
# Qt
 
35
from PyQt5.QtCore import *
 
36
from PyQt5.QtGui import *
 
37
from PyQt5.QtWidgets import *
 
38
 
 
39
 
 
40
 
 
41
class RangeValidator(QValidator):
 
42
    def __init__(self, parent=None, name=None):
 
43
        QValidator.__init__(self, parent) #, name)
 
44
 
 
45
 
 
46
    def validate(self, input, pos):
 
47
        for x in to_unicode(input)[pos-1:]:
 
48
            if x not in to_unicode('0123456789,- '):
 
49
                return QValidator.Invalid, input, pos
 
50
            return QValidator.Acceptable, input, pos
 
51
 
 
52
 
 
53
class PinValidator(QValidator):
 
54
    def __init__(self, parent=None, name=None):
 
55
        QValidator.__init__(self, parent) #, name)
 
56
 
 
57
 
 
58
    def validate(self, input, pos):
 
59
        for x in to_unicode(input)[pos-1:]:
 
60
            if x not in to_unicode('0123456789'):
 
61
                return QValidator.Invalid, input, pos
 
62
 
 
63
            return QValidator.Acceptable, input, pos
 
64
 
 
65
 
 
66
class UsernameAndJobnameValidator(QValidator):
 
67
    def __init__(self, parent=None, name=None):
 
68
        QValidator.__init__(self, parent) #, name)
 
69
 
 
70
 
 
71
    def validate(self, input, pos):
 
72
        for x in to_unicode(input)[pos-1:]:
 
73
            if x in to_unicode(' /=,.:;\'"[]{}-+!@#$%^&*()'):
 
74
                return QValidator.Invalid, input, pos
 
75
            return QValidator.Acceptable, input, pos
 
76
 
 
77
 
 
78
class OptionComboBox(QComboBox):
 
79
    def __init__(self, rw, parent, name, group, option, choices, default,
 
80
                 typ=cups.PPD_UI_PICKONE, other=None, job_option=False):
 
81
        QComboBox.__init__(self, parent)
 
82
        # rw?
 
83
        self.group = group
 
84
        self.option = option
 
85
        self.choices = choices
 
86
        self.default = default
 
87
        self.typ = typ
 
88
        self.other = other
 
89
        self.job_option = job_option
 
90
        self.setObjectName(name)
 
91
 
 
92
 
 
93
    def setDefaultPushbutton(self, pushbutton):
 
94
        self.pushbutton = pushbutton
 
95
 
 
96
 
 
97
    def setOther(self, other):
 
98
        self.other = other
 
99
 
 
100
 
 
101
 
 
102
class OptionSpinBox(QSpinBox):
 
103
    def __init__(self,  parent, name, group, option, default, job_option=False):
 
104
        QSpinBox.__init__(self, parent)
 
105
        self.group = group
 
106
        self.option = option
 
107
        self.default = default
 
108
        self.job_option = job_option
 
109
        self.setObjectName(name)
 
110
 
 
111
 
 
112
    def setDefaultPushbutton(self, pushbutton):
 
113
        self.pushbutton = pushbutton
 
114
 
 
115
 
 
116
 
 
117
class OptionRadioButton(QRadioButton):
 
118
    def __init__(self, parent, name, group, option, default, job_option=False):
 
119
        QRadioButton.__init__(self, parent)
 
120
        self.group = group
 
121
        self.option = option
 
122
        self.default = default
 
123
        self.job_option = job_option
 
124
        self.setObjectName(name)
 
125
 
 
126
 
 
127
    def setDefaultPushbutton(self, pushbutton):
 
128
        self.pushbutton = pushbutton
 
129
 
 
130
 
 
131
 
 
132
class DefaultPushButton(QPushButton):
 
133
    def __init__(self,  parent, name, group, option, choices,
 
134
                 default, control, typ, job_option=False):
 
135
        QPushButton.__init__(self, parent)
 
136
        self.group = group
 
137
        self.option = option
 
138
        self.default = default
 
139
        self.control = control
 
140
        self.typ = typ
 
141
        self.choices = choices
 
142
        self.job_option = job_option
 
143
        self.setObjectName(name)
 
144
 
 
145
 
 
146
#class PageRangeRadioButton(QRadioButton):
 
147
#    def __init__(self, parent, page_range_edit):
 
148
#        QRadioButton.__init__(self, parent):
 
149
#            self.page_range_edit = page_range_edit
 
150
 
 
151
 
 
152
class PageRangeRadioButton(QRadioButton):
 
153
    def __init__(self, parent, name, group, option, default): #, edit_control=None ):
 
154
        QRadioButton.__init__(self, parent)
 
155
        self.group = group
 
156
        self.option = option
 
157
        self.default = default
 
158
        self.job_option = True
 
159
        self.setObjectName(name)
 
160
 
 
161
 
 
162
    def setRangeEdit(self, edit_control):
 
163
        self.edit_control = edit_control
 
164
 
 
165
 
 
166
    def setDefaultPushbutton(self, pushbutton):
 
167
        self.pushbutton = pushbutton
 
168
 
 
169
 
 
170
 
 
171
class PrintSettingsToolbox(QToolBox):
 
172
    def __init__(self, parent, include_job_options=False):
 
173
        QToolBox.__init__(self, parent)
 
174
        self.include_job_options = include_job_options
 
175
        self.plus_icon = QIcon(load_pixmap('plus', '16x16'))
 
176
        self.minus_icon = QIcon(load_pixmap('minus', '16x16'))
 
177
        self.last_item = 0
 
178
        self.job_options = {}
 
179
        self.job_storage_enable = False
 
180
 
 
181
        # self.currentChanged[int].connect(self.PrintSettingsToolbox_currentChanged)
 
182
        self.currentChanged[int].connect(self.PrintSettingsToolbox_currentChanged)
 
183
 
 
184
 
 
185
    def getPrintCommands(self, file_list=None):
 
186
        # File list: [(path, mime_type, mime_desc, title, num_pages), ...]
 
187
        if file_list is None or not file_list:
 
188
            return []
 
189
 
 
190
        print_commands = []
 
191
 
 
192
        try:
 
193
            copies = int(self.job_options['copies'])
 
194
        except ValueError:
 
195
            copies = 1
 
196
 
 
197
        if copies < 1:
 
198
            copies = 1
 
199
            log.warning("Copies < 1, setting to 1.")
 
200
        elif copies > 99:
 
201
            copies = 99
 
202
            log.warning("Copies > 99, setting to 99.")
 
203
 
 
204
        #page_range = unicode(self.pageRangeEdit.text())
 
205
        page_range = self.job_options['pagerange']
 
206
 
 
207
        try:
 
208
            x = utils.expand_range(page_range)
 
209
        except ValueError:
 
210
            log.error("Invalid page range: %s" % page_range)
 
211
            return []
 
212
 
 
213
        all_pages = not page_range
 
214
        #page_set = int(self.pageSetComboBox.currentItem())
 
215
        page_set = self.job_options['pageset']
 
216
 
 
217
        cups.resetOptions()
 
218
        cups.openPPD(self.cur_printer)
 
219
        current_options = dict(cups.getOptions())
 
220
        cups.closePPD()
 
221
 
 
222
        nup = int(current_options.get("number-up", 1))
 
223
        psnup = utils.which('psnup')
 
224
 
 
225
        for p, t, d, title, num_pages in file_list:
 
226
            alt_nup = (nup > 1 and t == 'application/postscript' and psnup)
 
227
 
 
228
            if utils.which('lpr'):
 
229
                if alt_nup:
 
230
                    cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lpr -P', self.cur_printer])
 
231
                else:
 
232
                    cmd = ' '.join(['lpr -P', self.cur_printer])
 
233
 
 
234
                if copies > 1:
 
235
                    cmd = ' '.join([cmd, '-#%d' % copies])
 
236
 
 
237
            else: # lp
 
238
                if alt_nup:
 
239
                    cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lp -c -d', self.cur_printer])
 
240
                else:
 
241
                    cmd = ' '.join(['lp -c -d', self.cur_printer])
 
242
 
 
243
                if copies > 1:
 
244
                    cmd = ' '.join([cmd, '-n%d' % copies])
 
245
 
 
246
 
 
247
            if not all_pages and page_range:
 
248
                cmd = ' '.join([cmd, '-o page-ranges=%s' % page_range])
 
249
 
 
250
            if page_set:
 
251
                cmd = ' '.join([cmd, '-o page-set=%s' % page_set])
 
252
 
 
253
            # Job Storage
 
254
            # self.job_storage_mode = (0=Off, 1=P&H, 2=PJ, 3=QC, 4=SJ)
 
255
            # self.job_storage_pin = u"" (dddd)
 
256
            # self.job_storage_use_pin = True|False
 
257
            # self.job_storage_username = u""
 
258
            # self.job_storage_auto_username = True|False
 
259
            # self.job_storage_jobname = u""
 
260
            # self.job_storage_auto_jobname = True|False
 
261
            # self.job_storage_job_exist = (0=replace, 1=job name+(1-99))
 
262
 
 
263
            if self.job_storage_enable:
 
264
                if self.job_storage_mode != JOB_STORAGE_TYPE_OFF:
 
265
                    if self.job_storage_mode == JOB_STORAGE_TYPE_PROOF_AND_HOLD:
 
266
                        cmd = ' '.join([cmd, '-o HOLD=PROOF'])
 
267
 
 
268
                    elif self.job_storage_mode == JOB_STORAGE_TYPE_PERSONAL:
 
269
                        if self.job_storage_use_pin:
 
270
                            cmd = ' '.join([cmd, '-o HOLD=ON'])
 
271
                            cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
 
272
                            cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
 
273
                        else:
 
274
                            cmd = ' '.join([cmd, '-o HOLD=PROOF'])
 
275
                            cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
 
276
 
 
277
                    elif self.job_storage_mode == JOB_STORAGE_TYPE_QUICK_COPY:
 
278
                        cmd = ' '.join([cmd, '-o HOLD=ON'])
 
279
                        cmd = ' '.join([cmd, '-o HOLDTYPE=PUBLIC'])
 
280
 
 
281
                    elif self.job_storage_mode == JOB_STORAGE_TYPE_STORE:
 
282
                        if self.job_storage_use_pin:
 
283
                            cmd = ' '.join([cmd, '-o HOLD=STORE'])
 
284
                            cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
 
285
                            cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
 
286
                        else:
 
287
                            cmd = ' '.join([cmd, '-o HOLD=STORE'])
 
288
 
 
289
                    cmd = ' '.join([cmd, '-o USERNAME=%s' % self.job_storage_username.encode('ascii')\
 
290
                        .replace(" ", "_")])
 
291
 
 
292
                    cmd = ' '.join([cmd, '-o JOBNAME=%s' % self.job_storage_jobname.encode('ascii')\
 
293
                        .replace(" ", "_")])
 
294
 
 
295
                    if self.job_storage_job_exist == 1:
 
296
                        cmd = ' '.join([cmd, '-o DUPLICATEJOB=APPEND'])
 
297
                    else:
 
298
                        cmd = ' '.join([cmd, '-o DUPLICATEJOB=REPLACE'])
 
299
 
 
300
                else: # Off
 
301
                    cmd = ' '.join([cmd, '-o HOLD=OFF'])
 
302
 
 
303
            if not alt_nup:
 
304
                cmd = ''.join([cmd, ' "', p, '"'])
 
305
 
 
306
            print_commands.append(cmd)
 
307
 
 
308
        return print_commands
 
309
 
 
310
 
 
311
    def PrintSettingsToolbox_currentChanged(self, i):
 
312
        if i != -1:
 
313
            self.setItemIcon(self.last_item, self.plus_icon)
 
314
            self.setItemIcon(i, self.minus_icon)
 
315
            self.last_item = i
 
316
 
 
317
 
 
318
    def updateUi(self, cur_device, cur_printer):
 
319
        #print "updateUi(%s, %s)" % (cur_device, cur_printer)
 
320
        self.cur_device = cur_device
 
321
        self.cur_printer = cur_printer
 
322
        
 
323
        while self.count():
 
324
            self.removeItem(0)
 
325
 
 
326
        self.loading = True
 
327
        cups.resetOptions()
 
328
        cups.openPPD(self.cur_printer)
 
329
        cur_outputmode = ""
 
330
 
 
331
        try:
 
332
            if 1:
 
333
            #try:
 
334
                current_options = dict(cups.getOptions())
 
335
 
 
336
                if self.include_job_options:
 
337
                    self.beginControlGroup("job_options", self.__tr("Job Options"))
 
338
 
 
339
                    # Num. copies (SPINNER)
 
340
                    try:
 
341
                        current = int(current_options.get('copies', '1'))
 
342
                    except ValueError:
 
343
                        current = 1
 
344
 
 
345
                    self.addControlRow("copies", self.__tr("Number of copies"),
 
346
                        cups.UI_SPINNER, current, (1, 99), 1, job_option=True)
 
347
                    self.job_options['copies'] = current
 
348
 
 
349
                    # page range RADIO + RANGE (custom)
 
350
                    current = current_options.get('pagerange', '')
 
351
 
 
352
                    self.addControlRow("pagerange", self.__tr("Page Range"),
 
353
                        cups.UI_PAGE_RANGE, current, None, None, job_option=True)
 
354
 
 
355
                    self.job_options['pagerange'] = current
 
356
 
 
357
                    # page set (COMBO/PICKONE)
 
358
                    current = current_options.get('pageset', 'all')
 
359
                    self.addControlRow("pageset", self.__tr("Page Set"),
 
360
                        cups.PPD_UI_PICKONE, current,
 
361
                        [('all', self.__tr("AllPages")),
 
362
                         ('even', self.__tr("Even")),
 
363
                         ('odd', self.__tr("Odd"))], 'all', job_option=True)
 
364
 
 
365
                    self.job_options['pageset'] = current
 
366
#                    if current == u'even':
 
367
#                        self.job_options["pageset"] = PAGE_SET_EVEN
 
368
#                    elif current == u'odd':
 
369
#                        self.job_options["pageset"] = PAGE_SET_ODD
 
370
#                    else:
 
371
#                        self.job_options["pageset"] = PAGE_SET_ALL
 
372
 
 
373
                    self.endControlGroup() # job_options
 
374
 
 
375
                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
 
376
                    self.beginControlGroup("basic", self.__tr("Basic"))
 
377
 
 
378
                    # Basic
 
379
                        # PageSize (in PPD section)
 
380
                        # orientation-requested
 
381
                        # sides
 
382
                        # outputorder
 
383
                        # Collate
 
384
 
 
385
                    current = current_options.get('orientation-requested', '3')
 
386
 
 
387
                    self.addControlRow("orientation-requested", self.__tr("Page Orientation"),
 
388
                        cups.PPD_UI_PICKONE, current,
 
389
                        [('3', self.__tr('Portrait')),
 
390
                         ('4', self.__tr('Landscape')),
 
391
                         ('5', self.__tr('Reverse landscape')),
 
392
                         ('6', self.__tr('Reverse portrait'))], '3')
 
393
 
 
394
                    log.debug("Option: orientation-requested")
 
395
                    log.debug("Current value: %s" % current)
 
396
 
 
397
                    duplexer = self.cur_device.dq.get('duplexer', 0)
 
398
                    log.debug("Duplexer = %d" % duplexer)
 
399
 
 
400
                    if duplexer:
 
401
                        current = current_options.get('sides', 'one-sided')
 
402
                        self.addControlRow("sides",
 
403
                            self.__tr("Duplex (Print on both sides of the page)"),
 
404
                            cups.PPD_UI_PICKONE, current,
 
405
                            [('one-sided',self.__tr('Single sided')),
 
406
                             ('two-sided-long-edge', self.__tr('Two sided (long edge)')),
 
407
                             ('two-sided-short-edge', self.__tr('Two sided (short edge)'))], 'one-sided')
 
408
 
 
409
                        log.debug("Option: sides")
 
410
                        log.debug("Current value: %s" % current)
 
411
 
 
412
                    current = current_options.get('outputorder', 'normal')
 
413
 
 
414
                    self.addControlRow("outputorder",
 
415
                        self.__tr("Output Order"),
 
416
                        cups.PPD_UI_PICKONE, current,
 
417
                        [('normal', self.__tr('Normal (Print first page first)')),
 
418
                         ('reverse', self.__tr('Reversed (Print last page first)'))], 'normal')
 
419
 
 
420
                    log.debug("Option: outputorder")
 
421
                    log.debug("Current value: %s" % current)
 
422
 
 
423
                    #If collate section is not in the PPD, only then add a collate section.
 
424
                    to_add = cups.duplicateSection("collate")
 
425
                    if to_add == 0:
 
426
                        current = utils.to_bool(current_options.get('Collate', '0'))
 
427
 
 
428
                        self.addControlRow("Collate",
 
429
                            self.__tr("Collate (Group together multiple copies)"),
 
430
                            cups.PPD_UI_BOOLEAN, current,
 
431
                            [], 0)
 
432
 
 
433
                        log.debug("Option: Collate")
 
434
                        log.debug("Current value: %s" % current)
 
435
 
 
436
                    self.endControlGroup()
 
437
 
 
438
                groups = cups.getGroupList()
 
439
 
 
440
                #print groups
 
441
 
 
442
                for g in groups:
 
443
                    if 'jobretention' in g.lower():
 
444
                        log.debug("HPJobRetention skipped.")
 
445
                        continue
 
446
 
 
447
                    try:
 
448
                        text, num_subgroups = cups.getGroup(g)
 
449
                    except TypeError:
 
450
                        log.warn("Group %s returned None" % g)
 
451
                        continue
 
452
 
 
453
                    read_only = 'install' in g.lower()
 
454
 
 
455
 
 
456
                    if g.lower() == 'printoutmode':
 
457
                        text = self.__tr("Quality (also see 'Printout Mode' under 'General')")
 
458
 
 
459
                    self.beginControlGroup(g, str(text))
 
460
 
 
461
                    log.debug("  Text: %s" % str(text))
 
462
                    log.debug("Num subgroups: %d" % num_subgroups)
 
463
 
 
464
                    options = cups.getOptionList(g)
 
465
 
 
466
                    #print options
 
467
 
 
468
                    for o in options:
 
469
                        log.debug("  Option: %s" % repr(o))
 
470
 
 
471
                        if 'pageregion' in o.lower():
 
472
                            log.debug("Page Region skipped.")
 
473
                            continue
 
474
 
 
475
                        try:
 
476
                            option_text, defchoice, conflicted, ui  = cups.getOption(g, o)
 
477
                        except TypeError:
 
478
                            log.warn("Option %s in group %s returned None" % (o, g))
 
479
                            continue
 
480
 
 
481
 
 
482
                        if o.lower() == 'quality':
 
483
                            option_text = self.__tr("Quality")
 
484
 
 
485
                        log.debug("    Text: %s" % repr(option_text))
 
486
                        log.debug("    Defchoice: %s" % repr(defchoice))
 
487
 
 
488
                        choices = cups.getChoiceList(g, o)
 
489
 
 
490
                        value = None
 
491
                        choice_data = []
 
492
                        for c in choices:
 
493
                            log.debug("    Choice: %s" % repr(c))
 
494
 
 
495
                            # TODO: Add custom paper size controls
 
496
                            if 'pagesize' in o.lower() and 'custom' in c.lower():
 
497
                                log.debug("Skipped.")
 
498
                                continue
 
499
 
 
500
                            choice_text, marked = cups.getChoice(g, o, c)
 
501
 
 
502
 
 
503
                            log.debug("      Text: %s" % repr(choice_text))
 
504
 
 
505
                            if marked:
 
506
                                value = c
 
507
 
 
508
                            choice_data.append((c, choice_text))
 
509
 
 
510
                        if o.lower() == 'outputmode':
 
511
                            if value is not None:
 
512
                                cur_outputmode = value
 
513
                            else:
 
514
                                cur_outputmode = defchoice                                
 
515
 
 
516
                        self.addControlRow(o, option_text, ui, value, choice_data, defchoice, read_only)
 
517
 
 
518
                    self.endControlGroup()
 
519
 
 
520
##                        if 'pagesize' in o.lower(): # and 'custom' in c.lower():
 
521
##                            current = 0.0
 
522
##                            width_widget = self.addControlRow(widget, "custom", "custom-width", self.__tr("Custom Paper Width"), cups.UI_UNITS_SPINNER,
 
523
##                                current, (0.0, 0.0), 0.0)
 
524
##
 
525
##                            current = 0.0
 
526
##                            height_widget = self.addControlRow("custom", "custom-height", self.__tr("Custom Paper Height"), cups.UI_UNITS_SPINNER,
 
527
##                                current, (0.0, 0.0), 0.0)
 
528
##
 
529
##                            if value.lower() == 'custom':
 
530
##                                pass
 
531
 
 
532
                # N-Up
 
533
                    # number-up
 
534
                    # number-up-layout
 
535
                    # page-border
 
536
 
 
537
                self.beginControlGroup("nup", self.__tr("N-Up (Multiple document pages per printed page)"))
 
538
                current = current_options.get('number-up', '1')
 
539
 
 
540
                self.addControlRow("number-up", self.__tr("Pages per Sheet"),
 
541
                    cups.PPD_UI_PICKONE, current,
 
542
                    [('1', self.__tr('1 page per sheet')),
 
543
                     ('2', self.__tr('2 pages per sheet')),
 
544
                     ('4', self.__tr('4 pages per sheet'))], '1')
 
545
 
 
546
                log.debug("  Option: number-up")
 
547
                log.debug("  Current value: %s" % current)
 
548
 
 
549
                current = current_options.get('number-up-layout', 'lrtb')
 
550
 
 
551
                self.addControlRow("number-up-layout", self.__tr("Layout"),
 
552
                    cups.PPD_UI_PICKONE, current,
 
553
                    [('btlr', self.__tr('Bottom to top, left to right')),
 
554
                     ('btrl', self.__tr('Bottom to top, right to left')),
 
555
                     ('lrbt', self.__tr('Left to right, bottom to top')),
 
556
                     ('lrtb', self.__tr('Left to right, top to bottom')),
 
557
                     ('rlbt', self.__tr('Right to left, bottom to top')),
 
558
                     ('rltb', self.__tr('Right to left, top to bottom')),
 
559
                     ('tblr', self.__tr('Top to bottom, left to right')),
 
560
                     ('tbrl', self.__tr('Top to bottom, right to left')) ], 'lrtb')
 
561
 
 
562
                log.debug("  Option: number-up-layout")
 
563
                log.debug("  Current value: %s" % current)
 
564
 
 
565
                current = current_options.get('page-border', 'none')
 
566
 
 
567
                self.addControlRow("page-border",
 
568
                    self.__tr("Printed Border Around Each Page"),
 
569
                    cups.PPD_UI_PICKONE, current,
 
570
                    [('double', self.__tr("Two thin borders")),
 
571
                     ("double-thick", self.__tr("Two thick borders")),
 
572
                     ("none", self.__tr("No border")),
 
573
                     ("single", self.__tr("One thin border")),
 
574
                     ("single-thick", self.__tr("One thick border"))], 'none')
 
575
 
 
576
                log.debug("  Option: page-border")
 
577
                log.debug("  Current value: %s" % current)
 
578
 
 
579
                self.endControlGroup()
 
580
 
 
581
                # Adjustment
 
582
                    # brightness
 
583
                    # gamma
 
584
 
 
585
                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
 
586
                    self.beginControlGroup("adjustment", self.__tr("Printout Appearance"))
 
587
 
 
588
                    current = int(current_options.get('brightness', 100))
 
589
 
 
590
                    log.debug("  Option: brightness")
 
591
                    log.debug("  Current value: %s" % current)
 
592
 
 
593
                    self.addControlRow("brightness", self.__tr("Brightness"),
 
594
                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")
 
595
 
 
596
                    current = int(current_options.get('gamma', 1000))
 
597
 
 
598
                    log.debug("  Option: gamma")
 
599
                    log.debug("  Current value: %s" % current)
 
600
 
 
601
                    self.addControlRow("gamma", self.__tr("Gamma"), cups.UI_SPINNER, current,
 
602
                        (1, 10000), 1000)
 
603
 
 
604
                    self.endControlGroup()
 
605
 
 
606
                # Margins (pts)
 
607
                    # page-left
 
608
                    # page-right
 
609
                    # page-top
 
610
                    # page-bottom
 
611
 
 
612
##                if 0:
 
613
##                    # TODO: cupsPPDPageSize() fails on LaserJets. How do we get margins in this case? Defaults?
 
614
##                    # PPD file for LJs has a HWMargin entry...
 
615
##                    page, page_width, page_len, left, bottom, right, top = cups.getPPDPageSize()
 
616
##
 
617
##                    right = page_width - right
 
618
##                    top = page_len - top
 
619
##
 
620
##                    self.addGroupHeading("margins", self.__tr("Margins"))
 
621
##                    current_top = current_options.get('page-top', 0) # pts
 
622
##                    current_bottom = current_options.get('page-bottom', 0) # pts
 
623
##                    current_left = current_options.get('page-left', 0) # pts
 
624
##                    current_right = current_options.get('page-right', 0) # pts
 
625
##
 
626
##                    log.debug("  Option: page-top")
 
627
##                    log.debug("  Current value: %s" % current_top)
 
628
##
 
629
##                    self.addControlRow("margins", "page-top", self.__tr("Top margin"),
 
630
##                        cups.UI_UNITS_SPINNER, current_top,
 
631
##                        (0, page_len), top)
 
632
##
 
633
##                    self.addControlRow("margins", "page-bottom", self.__tr("Bottom margin"),
 
634
##                        cups.UI_UNITS_SPINNER, current_bottom,
 
635
##                        (0, page_len), bottom)
 
636
##
 
637
##                    self.addControlRow("margins", "page-left", self.__tr("Right margin"),
 
638
##                        cups.UI_UNITS_SPINNER, current_left,
 
639
##                        (0, page_width), left)
 
640
##
 
641
##                    self.addControlRow("margins", "page-right", self.__tr("Left margin"),
 
642
##                        cups.UI_UNITS_SPINNER, current_right,
 
643
##                        (0, page_width), right)
 
644
 
 
645
                # Image Printing
 
646
                    # position
 
647
                    # natural-scaling
 
648
                    # saturation
 
649
                    # hue
 
650
 
 
651
                self.beginControlGroup("image", self.__tr("Image Printing"))
 
652
 
 
653
                current = utils.to_bool(current_options.get('fitplot', 'false'))
 
654
 
 
655
                self.addControlRow("fitplot",
 
656
                    self.__tr("Fit to Page"),
 
657
                    cups.PPD_UI_BOOLEAN, current,
 
658
                    [], 0)
 
659
 
 
660
                current = current_options.get('position', 'center')
 
661
 
 
662
                self.addControlRow("position", self.__tr("Position on Page"),
 
663
                    cups.PPD_UI_PICKONE, current,
 
664
                    [('center', self.__tr('Centered')),
 
665
                     ('top', self.__tr('Top')),
 
666
                     ('left', self.__tr('Left')),
 
667
                     ('right', self.__tr('Right')),
 
668
                     ('top-left', self.__tr('Top left')),
 
669
                     ('top-right', self.__tr('Top right')),
 
670
                     ('bottom', self.__tr('Bottom')),
 
671
                     ('bottom-left', self.__tr('Bottom left')),
 
672
                     ('bottom-right', self.__tr('Bottom right'))], 'center')
 
673
 
 
674
                log.debug("  Option: position")
 
675
                log.debug("  Current value: %s" % current)
 
676
 
 
677
                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
 
678
                    current = int(current_options.get('saturation', 100))
 
679
 
 
680
                    log.debug("  Option: saturation")
 
681
                    log.debug("  Current value: %s" % current)
 
682
 
 
683
                    self.addControlRow("saturation", self.__tr("Saturation"),
 
684
                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")
 
685
 
 
686
                    current = int(current_options.get('hue', 0))
 
687
 
 
688
                    log.debug("  Option: hue")
 
689
                    log.debug("  Current value: %s" % current)
 
690
 
 
691
                    self.addControlRow("hue", self.__tr("Hue (color shift/rotation)"),
 
692
                        cups.UI_SPINNER, current,
 
693
                        (-100, 100), 0)
 
694
 
 
695
                current = int(current_options.get('natural-scaling', 100))
 
696
 
 
697
                log.debug("  Option: natural-scaling")
 
698
                log.debug("  Current value: %s" % current)
 
699
 
 
700
                self.addControlRow("natural-scaling",
 
701
                    self.__tr('"Natural" Scaling (relative to image)'),
 
702
                    cups.UI_SPINNER, current, (1, 800), 100, suffix=" %")
 
703
 
 
704
                current = int(current_options.get('scaling', 100))
 
705
 
 
706
                log.debug("  Option: scaling")
 
707
                log.debug("  Current value: %s" % current)
 
708
 
 
709
                self.addControlRow("scaling", self.__tr("Scaling (relative to page)"),
 
710
                    cups.UI_SPINNER, current,
 
711
                    (1, 800), 100, suffix=" %")
 
712
 
 
713
                self.endControlGroup()
 
714
 
 
715
                # Misc
 
716
                    # PrettyPrint
 
717
                    # job-sheets
 
718
                    # mirror
 
719
 
 
720
                self.beginControlGroup("misc", self.__tr("Miscellaneous"))
 
721
 
 
722
                log.debug("Group: Misc")
 
723
 
 
724
                current = utils.to_bool(current_options.get('prettyprint', '0'))
 
725
 
 
726
                self.addControlRow("prettyprint",
 
727
                    self.__tr('"Pretty Print" Text Documents (Add headers and formatting)'),
 
728
                    cups.PPD_UI_BOOLEAN, current, [], 0)
 
729
 
 
730
                log.debug("  Option: prettyprint")
 
731
                log.debug("  Current value: %s" % current)
 
732
 
 
733
                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
 
734
                    current = current_options.get('job-sheets', 'none').split(',')
 
735
 
 
736
                    try:
 
737
                        start = current[0]
 
738
                    except IndexError:
 
739
                        start = 'none'
 
740
 
 
741
                    try:
 
742
                        end = current[1]
 
743
                    except IndexError:
 
744
                        end = 'none'
 
745
 
 
746
                    # TODO: Look for locally installed banner pages beyond the default CUPS ones?
 
747
                    self.addControlRow("job-sheets", self.__tr("Banner Pages"), cups.UI_BANNER_JOB_SHEETS,
 
748
                        (start, end),
 
749
                        [("none", self.__tr("No banner page")),
 
750
                         ('classified', self.__tr("Classified")),
 
751
                         ('confidential', self.__tr("Confidential")),
 
752
                         ('secret', self.__tr("Secret")),
 
753
                         ('standard', self.__tr("Standard")),
 
754
                         ('topsecret', self.__tr("Top secret")),
 
755
                         ('unclassified', self.__tr("Unclassified"))], ('none', 'none'))
 
756
 
 
757
                    log.debug("  Option: job-sheets")
 
758
                    log.debug("  Current value: %s,%s" % (start, end))
 
759
 
 
760
                current = utils.to_bool(current_options.get('mirror', '0'))
 
761
 
 
762
                self.addControlRow("mirror", self.__tr('Mirror Printing'),
 
763
                    cups.PPD_UI_BOOLEAN, current, [], 0)
 
764
 
 
765
                log.debug("  Option: mirror")
 
766
                log.debug("  Current value: %s" % current)
 
767
 
 
768
                self.endControlGroup()
 
769
                
 
770
                #Summary
 
771
                    #color input
 
772
                    #quality
 
773
                quality_attr_name = "OutputModeDPI"
 
774
                cur_outputmode_dpi = cups.findPPDAttribute(quality_attr_name, cur_outputmode)
 
775
                if cur_outputmode_dpi is not None:
 
776
                    log.debug("Adding Group: Summary outputmode is : %s" % cur_outputmode)
 
777
                    log.debug("Adding Group: Summary outputmode dpi is : %s" % to_unicode (cur_outputmode_dpi))
 
778
                    self.beginControlGroup("sumry", self.__tr("Summary"))
 
779
                    self.addControlRow("colorinput", self.__tr('Color Input / Black Render'),
 
780
                        cups.UI_INFO, to_unicode (cur_outputmode_dpi), [], read_only)
 
781
                    self.addControlRow("quality", self.__tr('Print Quality'),
 
782
                        cups.UI_INFO, cur_outputmode, [], read_only)
 
783
                    self.endControlGroup()
 
784
                    log.debug("End adding Group: Summary")
 
785
                   
 
786
 
 
787
                self.job_storage_enable = 0 #self.cur_device.mq.get('job-storage', JOB_STORAGE_DISABLE) == JOB_STORAGE_ENABLE
 
788
 
 
789
 
 
790
                if self.job_storage_enable:
 
791
                    self.job_storage_pin = to_unicode(current_options.get('HOLDKEY', '0000')[:4])
 
792
                    self.job_storage_username = to_unicode(current_options.get('USERNAME', prop.username)[:16])
 
793
                    self.job_storage_jobname = to_unicode(current_options.get('JOBNAME', to_unicode('Untitled'))[:16])
 
794
                    hold = to_unicode(current_options.get('HOLD', to_unicode('OFF')))
 
795
                    holdtype = to_unicode(current_options.get('HOLDTYPE', to_unicode('PUBLIC')))
 
796
                    self.job_storage_use_pin = False
 
797
                    duplicate = to_unicode(current_options.get('DUPLICATEJOB', to_unicode('REPLACE')))
 
798
                    self.job_storage_auto_username = True
 
799
                    self.job_storage_auto_jobname = True
 
800
                    self.job_storage_mode = JOB_STORAGE_TYPE_OFF
 
801
 
 
802
                    if hold == 'OFF':
 
803
                        self.job_storage_mode = JOB_STORAGE_TYPE_OFF
 
804
 
 
805
                    elif hold == 'ON':
 
806
                        if holdtype == to_unicode('PUBLIC'):
 
807
                            self.job_storage_mode = JOB_STORAGE_TYPE_QUICK_COPY
 
808
 
 
809
                        else: # 'PRIVATE'
 
810
                            self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL
 
811
                            self.job_storage_use_pin = True
 
812
 
 
813
                    elif hold == to_unicode('PROOF'):
 
814
                        if holdtype == to_unicode('PUBLIC'):
 
815
                            self.job_storage_mode = JOB_STORAGE_TYPE_PROOF_AND_HOLD
 
816
                        else:
 
817
                            self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL
 
818
                            self.job_storage_use_pin = True
 
819
 
 
820
                    elif hold == to_unicode('STORE'):
 
821
                        self.job_storage_mode = JOB_STORAGE_TYPE_STORE
 
822
                        self.job_storage_use_pin = (holdtype == 'PRIVATE')
 
823
 
 
824
                    if duplicate == to_unicode('REPLACE'):
 
825
                        self.job_storage_job_exist = JOB_STORAGE_EXISTING_JOB_REPLACE
 
826
                    else: # u'APPEND'
 
827
                        self.job_storage_job_exist = JOB_STORAGE_EXISTING_JOB_APPEND_1_99
 
828
 
 
829
                    # option, text, typ, value, choices, default, read_only=False, suffix="", job_option=False)
 
830
 
 
831
                    self.beginControlGroup("jobstorage", self.__tr("Job Storage and Secure Printing"))
 
832
 
 
833
                    self.addControlRow("job-storage-mode", self.__tr("Mode"),
 
834
                                       cups.UI_JOB_STORAGE_MODE, None, None, None)
 
835
 
 
836
                    self.addControlRow("job-storage-pin", self.__tr("Make job private (use PIN to print)"),
 
837
                                      cups.UI_JOB_STORAGE_PIN, None, None, None )
 
838
 
 
839
                    self.addControlRow("job-storage-username", self.__tr("User name (for job identification)"),
 
840
                                       cups.UI_JOB_STORAGE_USERNAME, None, None, None)
 
841
 
 
842
                    self.addControlRow("job-storage-id", self.__tr("Job name/ID (for job identification)"),
 
843
                                      cups.UI_JOB_STORAGE_ID, None, None, None)
 
844
 
 
845
                    self.addControlRow("job-storage-id-exists", self.__tr("If job name/ID already exists..."),
 
846
                                       cups.UI_JOB_STORAGE_ID_EXISTS, None, None, None)
 
847
 
 
848
                    self.endControlGroup()
 
849
                    self.updateJobStorageControls()
 
850
 
 
851
                # use: self.job_options['xxx'] so that values can be picked up by getPrintCommand(
 
852
 
 
853
 
 
854
            #except Exception, e:
 
855
                #log.exception()
 
856
            #    pass
 
857
 
 
858
        finally:
 
859
            cups.closePPD()
 
860
            self.loading = False
 
861
 
 
862
 
 
863
    def beginControlGroup(self, group, text):
 
864
        log.debug("BeginGroup: %s" % group)
 
865
        self.row = 0
 
866
        self.widget = QWidget()
 
867
        self.gridlayout = QGridLayout(self.widget)
 
868
        self.group = group
 
869
        self.text = text
 
870
 
 
871
 
 
872
    def endControlGroup(self):
 
873
        log.debug("EndGroup: %s" % self.group)
 
874
        spacer = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
 
875
        self.row += 1
 
876
        self.gridlayout.addItem(spacer, self.row, 0, 1, 1)
 
877
        i = self.addItem(self.widget, self.text)
 
878
 
 
879
        if i:
 
880
            self.setItemIcon(i, self.plus_icon)
 
881
        else:
 
882
            self.setItemIcon(i, self.minus_icon)
 
883
 
 
884
        self.widget, self.gridlayout = None, None
 
885
 
 
886
 
 
887
    def addControlRow(self, option, text, typ, value, choices, default, read_only=False, suffix="", job_option=False):
 
888
 
 
889
        if typ == cups.PPD_UI_BOOLEAN: # () On (*) Off widget
 
890
            HBoxLayout = QHBoxLayout()
 
891
            HBoxLayout.setObjectName("HBoxLayout")
 
892
 
 
893
            OptionLabel = QLabel(self.widget)
 
894
            OptionLabel.setObjectName("OptionLabel")
 
895
            HBoxLayout.addWidget(OptionLabel)
 
896
 
 
897
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
898
            HBoxLayout.addItem(SpacerItem)
 
899
 
 
900
            GroupBox = QFrame(self.widget)
 
901
 
 
902
            gridlayout1 = QGridLayout(GroupBox)
 
903
            OnRadioButton = OptionRadioButton(GroupBox, "OnRadioButton", self.group,
 
904
                                              option, default, job_option)
 
905
            gridlayout1.addWidget(OnRadioButton,0,0,1,1)
 
906
            OffRadioButton = OptionRadioButton(GroupBox, "OffRadioButton", self.group,
 
907
                                               option, default, job_option)
 
908
            gridlayout1.addWidget(OffRadioButton,0,1,1,1)
 
909
            HBoxLayout.addWidget(GroupBox)
 
910
 
 
911
            DefaultButton = DefaultPushButton(self.widget, "defaultPushButton", self.group, option,
 
912
                choices, default, (OnRadioButton, OffRadioButton), typ, job_option)
 
913
 
 
914
            #GroupBox.setDefaultPushbutton(DefaultButton)
 
915
            OnRadioButton.setDefaultPushbutton(DefaultButton)
 
916
            OffRadioButton.setDefaultPushbutton(DefaultButton)
 
917
 
 
918
            HBoxLayout.addWidget(DefaultButton)
 
919
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
920
 
 
921
            OptionLabel.setText(text)
 
922
            OnRadioButton.setText(self.__tr("On"))
 
923
            OffRadioButton.setText(self.__tr("Off"))
 
924
 
 
925
            DefaultButton.setText("Default")
 
926
 
 
927
            #type of 'value' and 'default' can be unicode (ppd values), str, int or boolean, so we need to typecast it to bool for easy comparison
 
928
            if value == True or value == 'True' or value == 'true':
 
929
               value = True;
 
930
            else:
 
931
               value = False;
 
932
 
 
933
            if default == True or default == 'True' or default == 'true':
 
934
               default = True;
 
935
            else:
 
936
               default = False;
 
937
 
 
938
            if value == default:
 
939
                DefaultButton.setEnabled(False)
 
940
            DefaultButton.clicked.connect(self.DefaultButton_clicked)
 
941
 
 
942
            if value:
 
943
                OnRadioButton.setChecked(True)
 
944
            else:
 
945
                OffRadioButton.setChecked(True)
 
946
            OnRadioButton.toggled[bool].connect(self.BoolRadioButtons_clicked)
 
947
 
 
948
            if read_only:
 
949
                OnRadioButton.setEnabled(False)
 
950
                OffRadioButton.setEnabled(False)
 
951
                DefaultButton.setEnabled(False)
 
952
 
 
953
 
 
954
 
 
955
        elif typ == cups.PPD_UI_PICKONE: # Combo box widget
 
956
            #print option, job_option
 
957
            HBoxLayout = QHBoxLayout()
 
958
            HBoxLayout.setObjectName("HBoxLayout")
 
959
 
 
960
            OptionLabel = QLabel(self.widget)
 
961
            OptionLabel.setObjectName("OptionLabel")
 
962
            HBoxLayout.addWidget(OptionLabel)
 
963
 
 
964
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
965
            HBoxLayout.addItem(SpacerItem)
 
966
 
 
967
            ComboBox = OptionComboBox(0, self.widget, "ComboBox", self.group, option,
 
968
                                      choices, default, typ, None, job_option)
 
969
 
 
970
            HBoxLayout.addWidget(ComboBox)
 
971
 
 
972
            DefaultButton = DefaultPushButton(self.widget, "DefaultButton", self.group, option,
 
973
                choices, default, ComboBox, typ, job_option)
 
974
 
 
975
            ComboBox.setDefaultPushbutton(DefaultButton)
 
976
            HBoxLayout.addWidget(DefaultButton)
 
977
 
 
978
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
979
 
 
980
            OptionLabel.setText(text)
 
981
            DefaultButton.setText("Default")
 
982
 
 
983
            i, x, y = 0, None, None
 
984
            for c, t in choices:
 
985
                d = c.lower()
 
986
                if value is not None and d == value.lower():
 
987
                    x = i
 
988
 
 
989
                if d == default.lower():
 
990
                    y = t
 
991
 
 
992
                ComboBox.insertItem(i, t)
 
993
                i += 1
 
994
 
 
995
            if x is not None:
 
996
                ComboBox.setCurrentIndex(x)
 
997
            else:
 
998
                ComboBox.setCurrentIndex(0)
 
999
 
 
1000
            if value is not None and value.lower() == default.lower():
 
1001
                DefaultButton.setEnabled(False)
 
1002
 
 
1003
            #self.linkPrintoutModeAndQuality(option, value)
 
1004
#
 
1005
#            if read_only:
 
1006
#                optionComboBox.setEnabled(False)
 
1007
#                defaultPushButton.setEnabled(False)
 
1008
#            elif y is not None:
 
1009
#                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "%1".').arg(y))
 
1010
#
 
1011
 
 
1012
            DefaultButton.clicked.connect(self.DefaultButton_clicked)
 
1013
            ComboBox.currentIndexChanged["const QString &"].connect(self.ComboBox_indexChanged)
 
1014
            ComboBox.highlighted["const QString &"].connect(self.ComboBox_highlighted)
 
1015
 
 
1016
            control = ComboBox
 
1017
 
 
1018
        elif typ == cups.UI_SPINNER: # Spinner widget
 
1019
 
 
1020
            HBoxLayout = QHBoxLayout()
 
1021
            HBoxLayout.setObjectName("HBoxLayout")
 
1022
 
 
1023
            OptionLabel = QLabel(self.widget)
 
1024
            OptionLabel.setObjectName("OptionLabel")
 
1025
            HBoxLayout.addWidget(OptionLabel)
 
1026
 
 
1027
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1028
            HBoxLayout.addItem(SpacerItem)
 
1029
 
 
1030
            SpinBox = OptionSpinBox(self.widget,"SpinBox", self.group, option, default, job_option)
 
1031
            HBoxLayout.addWidget(SpinBox)
 
1032
 
 
1033
            DefaultButton = DefaultPushButton(self.widget,"DefaultButton", self.group, option,
 
1034
                choices, default, SpinBox, typ, job_option)
 
1035
 
 
1036
            SpinBox.setDefaultPushbutton(DefaultButton)
 
1037
            HBoxLayout.addWidget(DefaultButton)
 
1038
 
 
1039
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1040
 
 
1041
            min, max = choices
 
1042
            SpinBox.setMinimum(min)
 
1043
            SpinBox.setMaximum(max)
 
1044
            SpinBox.setValue(value)
 
1045
 
 
1046
            if suffix:
 
1047
                SpinBox.setSuffix(suffix)
 
1048
 
 
1049
            OptionLabel.setText(text)
 
1050
            DefaultButton.setText("Default")
 
1051
 
 
1052
            SpinBox.valueChanged[int].connect(self.SpinBox_valueChanged)
 
1053
            DefaultButton.clicked.connect(self.DefaultButton_clicked)
 
1054
 
 
1055
            DefaultButton.setEnabled(not value == default)
 
1056
 
 
1057
            if read_only:
 
1058
                SpinBox.setEnabled(False)
 
1059
                DefaultButton.setEnabled(False)
 
1060
 
 
1061
        elif typ == cups.UI_BANNER_JOB_SHEETS:  # Job sheets widget
 
1062
            HBoxLayout = QHBoxLayout()
 
1063
            HBoxLayout.setObjectName("HBoxLayout")
 
1064
 
 
1065
            OptionLabel = QLabel(self.widget)
 
1066
            OptionLabel.setObjectName("OptionLabel")
 
1067
            HBoxLayout.addWidget(OptionLabel)
 
1068
 
 
1069
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1070
            HBoxLayout.addItem(SpacerItem)
 
1071
 
 
1072
            StartLabel = QLabel(self.widget)
 
1073
            HBoxLayout.addWidget(StartLabel)
 
1074
 
 
1075
            StartComboBox = OptionComboBox(0, self.widget, "StartComboBox", self.group,
 
1076
                "start", choices, default, typ)
 
1077
 
 
1078
            HBoxLayout.addWidget(StartComboBox)
 
1079
 
 
1080
            EndLabel = QLabel(self.widget)
 
1081
            HBoxLayout.addWidget(EndLabel)
 
1082
 
 
1083
            EndComboBox = OptionComboBox(0, self.widget, "EndComboBox", self.group, "end", choices,
 
1084
                default, typ, StartComboBox)
 
1085
 
 
1086
            HBoxLayout.addWidget(EndComboBox)
 
1087
 
 
1088
            StartComboBox.setOther(EndComboBox)
 
1089
 
 
1090
            DefaultButton = DefaultPushButton(self.widget, "DefaultButton", self.group, option, choices,
 
1091
                default, (StartComboBox, EndComboBox), typ, job_option)
 
1092
 
 
1093
            HBoxLayout.addWidget(DefaultButton)
 
1094
 
 
1095
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1096
 
 
1097
            StartComboBox.setDefaultPushbutton(DefaultButton)
 
1098
            EndComboBox.setDefaultPushbutton(DefaultButton)
 
1099
 
 
1100
            OptionLabel.setText(text)
 
1101
            DefaultButton.setText("Default")
 
1102
 
 
1103
            StartLabel.setText(self.__tr("Start:"))
 
1104
            EndLabel.setText(self.__tr("End:"))
 
1105
 
 
1106
            s, e, y, z = None, None, None, None
 
1107
            for c, t in choices:
 
1108
                d = c.lower()
 
1109
                if value is not None:
 
1110
                    if d == value[0].lower():
 
1111
                        s = t
 
1112
 
 
1113
                    if d == value[1].lower():
 
1114
                        e = t
 
1115
 
 
1116
                if d == default[0].lower():
 
1117
                    y = t
 
1118
 
 
1119
                if d == default[1].lower():
 
1120
                    z = t
 
1121
 
 
1122
                StartComboBox.insertItem(0, t)
 
1123
                EndComboBox.insertItem(0, t)
 
1124
 
 
1125
            if s is not None:
 
1126
                StartComboBox.setCurrentIndex(StartComboBox.findText(s))
 
1127
 
 
1128
            if e is not None:
 
1129
                EndComboBox.setCurrentIndex(EndComboBox.findText(e))
 
1130
 
 
1131
            if value is not None and \
 
1132
                value[0].lower() == default[0].lower() and \
 
1133
                value[1].lower() == default[1].lower():
 
1134
 
 
1135
                DefaultButton.setEnabled(False)
 
1136
 
 
1137
            StartComboBox.activated["const QString&"].connect(self.BannerComboBox_activated)
 
1138
            EndComboBox.activated["const QString&"].connect(self.BannerComboBox_activated)
 
1139
            DefaultButton.clicked.connect(self.DefaultButton_clicked)
 
1140
 
 
1141
        elif typ == cups.PPD_UI_PICKMANY:
 
1142
            log.error("Unrecognized type: pickmany")
 
1143
 
 
1144
        elif typ == cups.UI_UNITS_SPINNER:
 
1145
            log.error("Unrecognized type: units spinner")
 
1146
 
 
1147
        elif typ == cups.UI_PAGE_RANGE:
 
1148
            HBoxLayout = QHBoxLayout()
 
1149
            HBoxLayout.setObjectName("HBoxLayout")
 
1150
 
 
1151
            OptionLabel = QLabel(self.widget)
 
1152
            OptionLabel.setObjectName("OptionLabel")
 
1153
            HBoxLayout.addWidget(OptionLabel)
 
1154
 
 
1155
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1156
            HBoxLayout.addItem(SpacerItem)
 
1157
 
 
1158
            GroupBox = QFrame(self.widget)
 
1159
 
 
1160
            gridlayout1 = QGridLayout(GroupBox)
 
1161
 
 
1162
            AllRadioButton = PageRangeRadioButton(GroupBox, "AllRadioButton",
 
1163
                                               self.group, option, default)
 
1164
 
 
1165
            gridlayout1.addWidget(AllRadioButton,0,0,1,1)
 
1166
            RangeRadioButton = PageRangeRadioButton(GroupBox, "RangeRadioButton",
 
1167
                                                 self.group, option, default)
 
1168
 
 
1169
            gridlayout1.addWidget(RangeRadioButton,0,1,1,1)
 
1170
            HBoxLayout.addWidget(GroupBox)
 
1171
 
 
1172
            PageRangeEdit = QLineEdit(self.widget)
 
1173
            HBoxLayout.addWidget(PageRangeEdit)
 
1174
            PageRangeEdit.setValidator(RangeValidator(PageRangeEdit))
 
1175
 
 
1176
            AllRadioButton.setRangeEdit(PageRangeEdit)
 
1177
            RangeRadioButton.setRangeEdit(PageRangeEdit)
 
1178
 
 
1179
            DefaultButton = DefaultPushButton(self.widget, "defaultPushButton", self.group, option,
 
1180
                choices, default, (AllRadioButton, RangeRadioButton, PageRangeEdit), typ, job_option)
 
1181
 
 
1182
            AllRadioButton.setDefaultPushbutton(DefaultButton)
 
1183
            RangeRadioButton.setDefaultPushbutton(DefaultButton)
 
1184
 
 
1185
            HBoxLayout.addWidget(DefaultButton)
 
1186
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1187
 
 
1188
            OptionLabel.setText(text)
 
1189
            AllRadioButton.setText(self.__tr("All pages"))
 
1190
            RangeRadioButton.setText(self.__tr("Page Range:"))
 
1191
 
 
1192
            DefaultButton.setText("Default")
 
1193
            DefaultButton.setEnabled(False)
 
1194
 
 
1195
            AllRadioButton.setChecked(True)
 
1196
            PageRangeEdit.setEnabled(False)
 
1197
 
 
1198
            # TODO: Set current
 
1199
 
 
1200
            AllRadioButton.toggled[bool].connect(self.PageRangeAllRadio_toggled)
 
1201
            RangeRadioButton.toggled[bool].connect(self.PageRangeRangeRadio_toggled)
 
1202
            DefaultButton.clicked.connect(self.DefaultButton_clicked)
 
1203
            PageRangeEdit.textChanged["const QString &"].connect(self.PageRangeEdit_textChanged)
 
1204
            PageRangeEdit.editingFinished.connect(self.PageRangeEdit_editingFinished)
 
1205
 
 
1206
        elif typ == cups.UI_JOB_STORAGE_MODE:
 
1207
            HBoxLayout = QHBoxLayout()
 
1208
            HBoxLayout.setObjectName("HBoxLayout")
 
1209
 
 
1210
            OptionLabel = QLabel(self.widget)
 
1211
            OptionLabel.setObjectName("OptionLabel")
 
1212
            HBoxLayout.addWidget(OptionLabel)
 
1213
 
 
1214
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1215
            HBoxLayout.addItem(SpacerItem)
 
1216
 
 
1217
            self.JobStorageModeComboBox = QComboBox(self.widget)
 
1218
            HBoxLayout.addWidget(self.JobStorageModeComboBox)
 
1219
 
 
1220
            self.JobStorageModeDefaultButton = QPushButton(self.widget)
 
1221
            HBoxLayout.addWidget(self.JobStorageModeDefaultButton)
 
1222
 
 
1223
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1224
 
 
1225
            OptionLabel.setText(text)
 
1226
            self.JobStorageModeDefaultButton.setText(self.__tr("Default"))
 
1227
 
 
1228
            self.JobStorageModeComboBox.addItem(self.__tr("Off/Disabled"), JOB_STORAGE_TYPE_OFF)
 
1229
            self.JobStorageModeComboBox.addItem(self.__tr("Proof and Hold"), JOB_STORAGE_TYPE_PROOF_AND_HOLD)
 
1230
            self.JobStorageModeComboBox.addItem(self.__tr("Personal/Private Job"), JOB_STORAGE_TYPE_PERSONAL)
 
1231
            self.JobStorageModeComboBox.addItem(self.__tr("Quick Copy"), JOB_STORAGE_TYPE_QUICK_COPY)
 
1232
            self.JobStorageModeComboBox.addItem(self.__tr("Stored Job"), JOB_STORAGE_TYPE_STORE)
 
1233
 
 
1234
            self.JobStorageModeComboBox.activated[int].connect( self.JobStorageModeComboBox_activated)
 
1235
 
 
1236
            self.JobStorageModeDefaultButton.clicked.connect( self.JobStorageModeDefaultButton_clicked)
 
1237
 
 
1238
 
 
1239
        elif typ == cups.UI_JOB_STORAGE_PIN:
 
1240
            HBoxLayout = QHBoxLayout()
 
1241
            HBoxLayout.setObjectName("HBoxLayout")
 
1242
 
 
1243
            OptionLabel = QLabel(self.widget)
 
1244
            OptionLabel.setObjectName("OptionLabel")
 
1245
            HBoxLayout.addWidget(OptionLabel)
 
1246
 
 
1247
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1248
            HBoxLayout.addItem(SpacerItem)
 
1249
 
 
1250
            self.JobStoragePinGroupBox = QFrame(self.widget)
 
1251
 
 
1252
            gridlayout1 = QGridLayout(self.JobStoragePinGroupBox)
 
1253
            self.JobStoragePinOffRadioButton = QRadioButton(self.JobStoragePinGroupBox)
 
1254
            gridlayout1.addWidget(self.JobStoragePinOffRadioButton, 0, 0, 1, 1)
 
1255
 
 
1256
            self.JobStoragePinPrivateRadioButton = QRadioButton(self.JobStoragePinGroupBox)
 
1257
            gridlayout1.addWidget(self.JobStoragePinPrivateRadioButton, 0, 1, 1, 1)
 
1258
 
 
1259
            self.JobStoragePinEdit = QLineEdit(self.JobStoragePinGroupBox)
 
1260
            self.JobStoragePinEdit.setMaxLength(4)
 
1261
            self.JobStoragePinEdit.setValidator(PinValidator(self.JobStoragePinEdit))
 
1262
            gridlayout1.addWidget(self.JobStoragePinEdit, 0, 2, 1, 1)
 
1263
 
 
1264
            HBoxLayout.addWidget(self.JobStoragePinGroupBox)
 
1265
 
 
1266
            self.JobStoragePinDefaultButton = QPushButton(self.widget)
 
1267
            HBoxLayout.addWidget(self.JobStoragePinDefaultButton)
 
1268
 
 
1269
            self.JobStoragePinOffRadioButton.setText(self.__tr("Public/Off"))
 
1270
            self.JobStoragePinPrivateRadioButton.setText(self.__tr("Private/Use PIN:"))
 
1271
 
 
1272
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1273
 
 
1274
            OptionLabel.setText(text)
 
1275
            self.JobStoragePinDefaultButton.setText(self.__tr("Default"))
 
1276
 
 
1277
            self.JobStoragePinOffRadioButton.toggled[bool].connect( self.JobStoragePinOffRadioButton_toggled)
 
1278
 
 
1279
            self.JobStoragePinPrivateRadioButton.toggled[bool].connect( self.JobStoragePinPrivateRadioButton_toggled)
 
1280
 
 
1281
            self.JobStoragePinDefaultButton.clicked.connect( self.JobStoragePinDefaultButton_clicked)
 
1282
 
 
1283
            self.JobStoragePinEdit.textEdited["const QString &"].connect( self.JobStoragePinEdit_textEdited)
 
1284
 
 
1285
 
 
1286
        elif typ == cups.UI_JOB_STORAGE_USERNAME:
 
1287
            HBoxLayout = QHBoxLayout()
 
1288
            HBoxLayout.setObjectName("HBoxLayout")
 
1289
 
 
1290
            OptionLabel = QLabel(self.widget)
 
1291
            OptionLabel.setObjectName("OptionLabel")
 
1292
            HBoxLayout.addWidget(OptionLabel)
 
1293
            OptionLabel.setText(text)
 
1294
 
 
1295
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1296
            HBoxLayout.addItem(SpacerItem)
 
1297
 
 
1298
            self.JobStorageUsernameGroupBox = QFrame(self.widget)
 
1299
 
 
1300
            gridlayout1 = QGridLayout(self.JobStorageUsernameGroupBox)
 
1301
            self.JobStorageUsernameAutoRadioButton = QRadioButton(self.JobStorageUsernameGroupBox)
 
1302
            gridlayout1.addWidget(self.JobStorageUsernameAutoRadioButton, 0, 0, 1, 1)
 
1303
 
 
1304
            self.JobStorageUsernameCustomRadioButton = QRadioButton(self.JobStorageUsernameGroupBox)
 
1305
            gridlayout1.addWidget(self.JobStorageUsernameCustomRadioButton, 0, 1, 1, 1)
 
1306
 
 
1307
            self.JobStorageUsernameEdit = QLineEdit(self.JobStorageUsernameGroupBox)
 
1308
            self.JobStorageUsernameEdit.setValidator(UsernameAndJobnameValidator(self.JobStorageUsernameEdit))
 
1309
            self.JobStorageUsernameEdit.setMaxLength(16)
 
1310
            gridlayout1.addWidget(self.JobStorageUsernameEdit, 0, 2, 1, 1)
 
1311
 
 
1312
            HBoxLayout.addWidget(self.JobStorageUsernameGroupBox)
 
1313
 
 
1314
            self.JobStorageUsernameDefaultButton = QPushButton(self.widget)
 
1315
            HBoxLayout.addWidget(self.JobStorageUsernameDefaultButton)
 
1316
 
 
1317
            self.JobStorageUsernameAutoRadioButton.setText(self.__tr("Automatic"))
 
1318
            self.JobStorageUsernameCustomRadioButton.setText(self.__tr("Custom:"))
 
1319
            self.JobStorageUsernameDefaultButton.setText(self.__tr("Default"))
 
1320
 
 
1321
            self.JobStorageUsernameAutoRadioButton.toggled[bool].connect( self.JobStorageUsernameAutoRadioButton_toggled)
 
1322
 
 
1323
            self.JobStorageUsernameCustomRadioButton.toggled[bool].connect( self.JobStorageUsernameCustomRadioButton_toggled)
 
1324
 
 
1325
            self.JobStorageUsernameDefaultButton.clicked.connect( self.JobStorageUsernameDefaultButton_clicked)
 
1326
 
 
1327
            self.JobStorageUsernameEdit.textEdited["const QString &"].connect( self.JobStorageUsernameEdit_textEdited)
 
1328
 
 
1329
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1330
 
 
1331
        elif typ == cups.UI_JOB_STORAGE_ID:
 
1332
            HBoxLayout = QHBoxLayout()
 
1333
            HBoxLayout.setObjectName("HBoxLayout")
 
1334
 
 
1335
            OptionLabel = QLabel(self.widget)
 
1336
            OptionLabel.setObjectName("OptionLabel")
 
1337
            HBoxLayout.addWidget(OptionLabel)
 
1338
            OptionLabel.setText(text)
 
1339
 
 
1340
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1341
            HBoxLayout.addItem(SpacerItem)
 
1342
 
 
1343
            self.JobStorageIDGroupBox = QFrame(self.widget)
 
1344
 
 
1345
            gridlayout1 = QGridLayout(self.JobStorageIDGroupBox)
 
1346
            self.JobStorageIDAutoRadioButton = QRadioButton(self.JobStorageIDGroupBox)
 
1347
            gridlayout1.addWidget(self.JobStorageIDAutoRadioButton, 0, 0, 1, 1)
 
1348
 
 
1349
            self.JobStorageIDCustomRadioButton = QRadioButton(self.JobStorageIDGroupBox)
 
1350
            gridlayout1.addWidget(self.JobStorageIDCustomRadioButton, 0, 1, 1, 1)
 
1351
 
 
1352
            self.JobStorageIDEdit = QLineEdit(self.JobStorageIDGroupBox)
 
1353
            self.JobStorageIDEdit.setValidator(UsernameAndJobnameValidator(self.JobStorageIDEdit))
 
1354
            self.JobStorageIDEdit.setMaxLength(16)
 
1355
            gridlayout1.addWidget(self.JobStorageIDEdit, 0, 2, 1, 1)
 
1356
 
 
1357
            HBoxLayout.addWidget(self.JobStorageIDGroupBox)
 
1358
 
 
1359
            self.JobStorageIDDefaultButton = QPushButton(self.widget)
 
1360
            HBoxLayout.addWidget(self.JobStorageIDDefaultButton)
 
1361
 
 
1362
            self.JobStorageIDAutoRadioButton.setText(self.__tr("Automatic"))
 
1363
            self.JobStorageIDCustomRadioButton.setText(self.__tr("Custom:"))
 
1364
            self.JobStorageIDDefaultButton.setText(self.__tr("Default"))
 
1365
 
 
1366
            self.JobStorageIDAutoRadioButton.toggled[bool].connect( self.JobStorageIDAutoRadioButton_toggled)
 
1367
 
 
1368
            self.JobStorageIDCustomRadioButton.toggled[bool].connect( self.JobStorageIDCustomRadioButton_toggled)
 
1369
 
 
1370
            self.JobStorageIDDefaultButton.clicked.connect( self.JobStorageIDDefaultButton_clicked)
 
1371
 
 
1372
            self.JobStorageIDEdit.textEdited["const QString &"].connect( self.JobStorageIDEdit_textEdited)
 
1373
 
 
1374
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1375
 
 
1376
        elif typ == cups.UI_JOB_STORAGE_ID_EXISTS:
 
1377
            HBoxLayout = QHBoxLayout()
 
1378
            HBoxLayout.setObjectName("HBoxLayout")
 
1379
 
 
1380
            OptionLabel = QLabel(self.widget)
 
1381
            OptionLabel.setObjectName("OptionLabel")
 
1382
            HBoxLayout.addWidget(OptionLabel)
 
1383
            OptionLabel.setText(text)
 
1384
 
 
1385
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1386
            HBoxLayout.addItem(SpacerItem)
 
1387
 
 
1388
            self.JobStorageExistingComboBox = QComboBox(self.widget)
 
1389
            HBoxLayout.addWidget(self.JobStorageExistingComboBox)
 
1390
 
 
1391
            self.JobStorageExistingDefaultButton = QPushButton(self.widget)
 
1392
            HBoxLayout.addWidget(self.JobStorageExistingDefaultButton)
 
1393
 
 
1394
            self.JobStorageExistingComboBox.addItem(self.__tr("Replace existing job"),
 
1395
                             JOB_STORAGE_EXISTING_JOB_REPLACE)
 
1396
 
 
1397
            self.JobStorageExistingComboBox.addItem(self.__tr("Use job name appended with 1-99"),
 
1398
                             JOB_STORAGE_EXISTING_JOB_APPEND_1_99)
 
1399
 
 
1400
            self.JobStorageExistingDefaultButton.setText(self.__tr("Default"))
 
1401
 
 
1402
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1403
 
 
1404
            self.JobStorageExistingComboBox.activated[int].connect( self.JobStorageExistingComboBox_activated)
 
1405
 
 
1406
            self.JobStorageExistingDefaultButton.clicked.connect( self.JobStorageExistingDefaultButton_clicked)
 
1407
                        
 
1408
        elif typ == cups.UI_INFO:
 
1409
            HBoxLayout = QHBoxLayout()
 
1410
            HBoxLayout.setObjectName("HBoxLayout")
 
1411
 
 
1412
            OptionName = QLabel(self.widget)
 
1413
            OptionName.setObjectName("OptionLabel")
 
1414
            HBoxLayout.addWidget(OptionName)
 
1415
            OptionName.setText(text)
 
1416
 
 
1417
            SpacerItem = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
 
1418
            HBoxLayout.addItem(SpacerItem)
 
1419
            
 
1420
            if text == 'Print Quality':
 
1421
                self.PQValueLabel = QLabel(self.widget)
 
1422
                self.PQValueLabel.setObjectName("PQValueLabel")
 
1423
                HBoxLayout.addWidget(self.PQValueLabel)
 
1424
                self.PQValueLabel.setText(value)
 
1425
            elif text == 'Color Input / Black Render':
 
1426
                self.PQColorInputLabel = QLabel(self.widget)
 
1427
                self.PQColorInputLabel.setObjectName("PQColorInputLabel")
 
1428
                HBoxLayout.addWidget(self.PQColorInputLabel)
 
1429
                self.PQColorInputLabel.setText(value)
 
1430
            else:
 
1431
                OptionValue = QLabel(self.widget)
 
1432
                OptionValue.setObjectName("OptionValue")
 
1433
                HBoxLayout.addWidget(OptionValue)
 
1434
                OptionValue.setText(value)
 
1435
                
 
1436
            self.gridlayout.addLayout(HBoxLayout, self.row, 0, 1, 1)
 
1437
 
 
1438
        else:
 
1439
            log.error("Invalid UI value: %s/%s" % (self.group, option))
 
1440
 
 
1441
        self.row += 1
 
1442
 
 
1443
 
 
1444
 
 
1445
    def BannerComboBox_activated(self, a): # cups.UI_BANNER_JOB_SHEETS
 
1446
        a = to_unicode(a)
 
1447
        sender = self.sender()
 
1448
        choice = None
 
1449
 
 
1450
        start, end = None, None
 
1451
        for c, t in sender.choices:
 
1452
            if t == a:
 
1453
                start = c
 
1454
                break
 
1455
 
 
1456
        for c, t in sender.other.choices:
 
1457
            if t == sender.other.currentText():
 
1458
                end = c
 
1459
                break
 
1460
 
 
1461
        if sender.option == 'end':
 
1462
            start, end = end, start
 
1463
 
 
1464
        if start is not None and \
 
1465
            end is not None and \
 
1466
            start.lower() == sender.default[0].lower() and \
 
1467
            end.lower() == sender.default[1].lower():
 
1468
                self.removePrinterOption('job-sheets')
 
1469
                sender.pushbutton.setEnabled(False)
 
1470
        else:
 
1471
            sender.pushbutton.setEnabled(True)
 
1472
 
 
1473
            if start is not None and \
 
1474
                end is not None:
 
1475
 
 
1476
                self.setPrinterOption('job-sheets', ','.join([start, end]))
 
1477
 
 
1478
 
 
1479
    def ComboBox_highlighted(self, t):
 
1480
        t = to_unicode(t)
 
1481
        sender = self.sender()
 
1482
        choice = None
 
1483
 
 
1484
        #print sender, sender.option, sender.job_option
 
1485
 
 
1486
        choice = None
 
1487
        for c, a in sender.choices:
 
1488
            if a == t:
 
1489
                choice = c
 
1490
                break
 
1491
 
 
1492
        if choice is not None and choice == sender.default:
 
1493
            if sender.job_option:
 
1494
                self.job_options[sender.option] = sender.default
 
1495
            else:
 
1496
                self.removePrinterOption(sender.option)
 
1497
            sender.pushbutton.setEnabled(False)
 
1498
 
 
1499
        else:
 
1500
            sender.pushbutton.setEnabled(True)
 
1501
 
 
1502
            if choice is not None:
 
1503
                if sender.job_option:
 
1504
                    self.job_options[sender.option] = choice
 
1505
                else:
 
1506
                    self.setPrinterOption(sender.option, choice)
 
1507
 
 
1508
            #self.linkPrintoutModeAndQuality(sender.option, choice)
 
1509
 
 
1510
    if 0:
 
1511
        pass
 
1512
        #    def linkPrintoutModeAndQuality(self, option, choice):
 
1513
        #        if option.lower() == 'quality' and \
 
1514
        #            choice is not None:
 
1515
        #
 
1516
        #            try:
 
1517
        #                c = self.items['o:PrintoutMode'].control
 
1518
        #            except KeyError:
 
1519
        #                return
 
1520
        #            else:
 
1521
        #                if c is not None:
 
1522
        #                    if choice.lower() == 'fromprintoutmode':
 
1523
        #                        # from printoutmode selected
 
1524
        #                        # determine printoutmode option combo enable state
 
1525
        #                        c.setEnabled(True)
 
1526
        #                        QToolTip.remove(c)
 
1527
        #                        a = unicode(c.currentText())
 
1528
        #
 
1529
        #                        # determine printoutmode default button state
 
1530
        #                        link_choice = None
 
1531
        #                        for x, t in c.choices:
 
1532
        #                            if t == a:
 
1533
        #                                link_choice = x
 
1534
        #                                break
 
1535
        #
 
1536
        #                        if link_choice is not None and \
 
1537
        #                            link_choice.lower() == c.default.lower():
 
1538
        #
 
1539
        #                            c.pushbutton.setEnabled(False)
 
1540
        #                        else:
 
1541
        #                            c.pushbutton.setEnabled(True)
 
1542
        #
 
1543
        #                    else: # fromprintoutmode not selected, disable printoutmode
 
1544
        #                        c.setEnabled(False)
 
1545
        #                        QToolTip.add(c, self.__tr("""Set Quality to "Controlled by 'Printout Mode'" to enable."""))
 
1546
        #                        c.pushbutton.setEnabled(False)
 
1547
        #
 
1548
 
 
1549
    def SpinBox_valueChanged(self, i): # cups.UI_SPINNER
 
1550
        sender = self.sender()
 
1551
 
 
1552
        if not sender.job_option:
 
1553
            if i == sender.default:
 
1554
                self.removePrinterOption(sender.option)
 
1555
                sender.pushbutton.setEnabled(False)
 
1556
            else:
 
1557
                sender.pushbutton.setEnabled(True)
 
1558
                self.setPrinterOption(sender.option, str(i))
 
1559
 
 
1560
        else:
 
1561
            try:
 
1562
                self.job_options[sender.option] = int(i)
 
1563
            except ValueError:
 
1564
                self.job_options[sender.option] = sender.default
 
1565
 
 
1566
 
 
1567
    def BoolRadioButtons_clicked(self, b): # cups.PPD_UI_BOOLEAN
 
1568
        sender = self.sender()
 
1569
        b = int(b)
 
1570
        if sender.default == True or sender.default == "True" or sender.default == "true":
 
1571
            sender.default = int(True)
 
1572
        else:
 
1573
            sender.default = int(False)
 
1574
 
 
1575
        if b == sender.default:
 
1576
            self.removePrinterOption(sender.option)
 
1577
            sender.pushbutton.setEnabled(False)
 
1578
        else:
 
1579
            sender.pushbutton.setEnabled(True)
 
1580
 
 
1581
            if b:
 
1582
                self.setPrinterOption(sender.option, "true")
 
1583
            else:
 
1584
                self.setPrinterOption(sender.option, "false")
 
1585
 
 
1586
    def ComboBox_indexChanged(self, currentItem):
 
1587
        sender = self.sender()
 
1588
        currentItem = to_unicode(currentItem)
 
1589
        # Checking for summary control
 
1590
        labelPQValaue = getattr(self, 'PQValueLabel', None)
 
1591
        labelPQColorInput = getattr(self, 'PQColorInputLabel', None)
 
1592
        # When output mode combo item is changed, we need to update the summary information      
 
1593
        if currentItem is not None and sender.option == 'OutputMode' and labelPQValaue is not None and labelPQColorInput is not None:
 
1594
            # Setting output mode
 
1595
            self.PQValueLabel.setText(currentItem)
 
1596
            
 
1597
            # Getting DPI custom attributefrom the PPD
 
1598
            # Setting color input
 
1599
            quality_attr_name = "OutputModeDPI"
 
1600
            cups.openPPD(self.cur_printer)
 
1601
            outputmode_dpi = cups.findPPDAttribute(quality_attr_name, currentItem)
 
1602
            log.debug("Outputmode changed, setting outputmode_dpi: %s" % outputmode_dpi)
 
1603
            cups.closePPD()            
 
1604
            self.PQColorInputLabel.setText(outputmode_dpi)
 
1605
            
 
1606
            log.debug("Outputmode changed, setting value outputmode: %s" % currentItem)            
 
1607
 
 
1608
    def DefaultButton_clicked(self):
 
1609
        sender = self.sender()
 
1610
        sender.setEnabled(False)
 
1611
 
 
1612
        if sender.typ == cups.PPD_UI_BOOLEAN: # () On  (*) Off
 
1613
            if sender.default == True or sender.default == 'True' or sender.default == 'true': 
 
1614
                sender.default = True
 
1615
            else:
 
1616
                sender.default = False
 
1617
            if sender.default:
 
1618
                sender.control[0].setChecked(True)
 
1619
                sender.control[0].setFocus(Qt.OtherFocusReason)
 
1620
            else:
 
1621
                sender.control[1].setChecked(True)
 
1622
                sender.control[1].setFocus(Qt.OtherFocusReason)
 
1623
 
 
1624
            if not sender.job_option:
 
1625
                self.removePrinterOption(sender.option)
 
1626
 
 
1627
        elif sender.typ == cups.PPD_UI_PICKONE: # [     \/]
 
1628
            choice, text = None, None
 
1629
 
 
1630
            for c, t in sender.choices:
 
1631
                if c == sender.default:
 
1632
                    choice = c
 
1633
                    text = t
 
1634
                    self.job_options[sender.option] = t
 
1635
                    break
 
1636
 
 
1637
            if choice is not None:
 
1638
                if not sender.job_option:
 
1639
                    self.removePrinterOption(sender.option)
 
1640
                index = sender.control.findText(text)
 
1641
                sender.control.setCurrentIndex(index)
 
1642
 
 
1643
                #self.linkPrintoutModeAndQuality(sender.option, choice) # TODO:
 
1644
                sender.control.setFocus(Qt.OtherFocusReason)
 
1645
 
 
1646
        elif sender.typ == cups.UI_SPINNER: # [ x /\|\/]
 
1647
            sender.control.setValue(sender.default)
 
1648
            if not sender.job_option:
 
1649
                self.removePrinterOption(sender.option)
 
1650
 
 
1651
            sender.control.setFocus(Qt.OtherFocusReason)
 
1652
 
 
1653
        elif sender.typ == cups.UI_BANNER_JOB_SHEETS: # start: [     \/]  end: [     \/]
 
1654
            start, end, start_text, end_text = None, None, None, None
 
1655
            for c, t in sender.choices:
 
1656
                if c == sender.default[0]:
 
1657
                    start = c
 
1658
                    start_text = t
 
1659
 
 
1660
                if c == sender.default[1]:
 
1661
                    end = c
 
1662
                    end_text = t
 
1663
 
 
1664
            if start is not None:
 
1665
                index = sender.control[0].findText(start_text)
 
1666
                sender.control[0].setCurrentIndex(index)
 
1667
 
 
1668
            if end is not None:
 
1669
                index = sender.control[1].findText(end_text)
 
1670
                sender.control[1].setCurrentIndex(index)
 
1671
 
 
1672
            if not sender.job_option:
 
1673
                self.removePrinterOption('job-sheets')
 
1674
 
 
1675
            sender.control[0].setFocus(Qt.OtherFocusReason)
 
1676
 
 
1677
        elif sender.typ == cups.UI_PAGE_RANGE: # (*) All () Pages: [    ]
 
1678
            sender.control[0].setChecked(True) # all radio button
 
1679
            sender.control[0].setFocus(Qt.OtherFocusReason)
 
1680
            sender.control[2].setEnabled(False) # range edit box
 
1681
 
 
1682
 
 
1683
    def PageRangeAllRadio_toggled(self, b):
 
1684
        if b:
 
1685
            sender = self.sender()
 
1686
            sender.edit_control.setEnabled(False)
 
1687
            sender.pushbutton.setEnabled(False)
 
1688
            self.job_options['pagerange'] = ''
 
1689
 
 
1690
 
 
1691
    def PageRangeRangeRadio_toggled(self, b):
 
1692
        if b:
 
1693
            sender = self.sender()
 
1694
            sender.pushbutton.setEnabled(True)
 
1695
            sender.edit_control.setEnabled(True)
 
1696
            self.job_options['pagerange'] = to_unicode(sender.edit_control.text())
 
1697
 
 
1698
 
 
1699
    def PageRangeEdit_editingFinished(self):
 
1700
        sender = self.sender()
 
1701
        t, ok, x = self.job_options['pagerange'], True, []
 
1702
 
 
1703
 
 
1704
        try:
 
1705
            x = utils.expand_range(t)   
 
1706
        except ValueError:
 
1707
            ok = False
 
1708
 
 
1709
        if ok:
 
1710
            for y in x:
 
1711
                if y <= 0  or y > 999:
 
1712
                    ok = False
 
1713
                    break
 
1714
 
 
1715
        if not ok:
 
1716
            self.job_options['pagerange'] = ''
 
1717
            log.error("Invalid page range: %s" % t)
 
1718
            FailureUI(self, self.__tr("<b>Invalid page range.</b><p>Please enter a range using page numbers (1-999), dashes, and commas. For example: 1-2,3,5-7</p>"))
 
1719
            sender.setFocus(Qt.OtherFocusReason)
 
1720
 
 
1721
 
 
1722
    def PageRangeEdit_textChanged(self, t):
 
1723
        self.job_options['pagerange'] = to_unicode(t) # Do range validation only in PageRangeEdit_editingFinished method
 
1724
 
 
1725
    #
 
1726
    # Job Storage
 
1727
    #
 
1728
 
 
1729
    def updateJobStorageControls(self):
 
1730
        beginWaitCursor()
 
1731
        try:
 
1732
            # Mode
 
1733
            self.JobStorageModeComboBox.setCurrentIndex(self.JobStorageModeComboBox.findData(self.job_storage_mode))
 
1734
            self.JobStorageModeDefaultButton.setEnabled(self.job_storage_mode != JOB_STORAGE_TYPE_OFF)
 
1735
 
 
1736
            # PIN
 
1737
            self.JobStoragePinPrivateRadioButton.setChecked(self.job_storage_use_pin)
 
1738
 
 
1739
            # Username
 
1740
            self.JobStorageUsernameAutoRadioButton.setChecked(self.job_storage_auto_username)
 
1741
 
 
1742
            # Jobname/ID
 
1743
            self.JobStorageIDAutoRadioButton.setChecked(self.job_storage_auto_jobname)
 
1744
 
 
1745
            # Dup/existing ID
 
1746
            self.JobStorageExistingComboBox.setCurrentIndex(self.JobStorageExistingComboBox.findData(self.job_storage_job_exist))
 
1747
 
 
1748
            if self.job_storage_mode == JOB_STORAGE_TYPE_OFF:
 
1749
                # PIN
 
1750
                self.JobStoragePinGroupBox.setEnabled(False)
 
1751
                self.JobStoragePinEdit.setEnabled(False)
 
1752
                self.JobStoragePinDefaultButton.setEnabled(False)
 
1753
                self.JobStoragePinEdit.setText(str())
 
1754
 
 
1755
                # Username
 
1756
                self.JobStorageUsernameGroupBox.setEnabled(False)
 
1757
                self.JobStorageUsernameEdit.setEnabled(False)
 
1758
                self.JobStorageUsernameDefaultButton.setEnabled(False)
 
1759
 
 
1760
                # Jobname/ID
 
1761
                self.JobStorageIDGroupBox.setEnabled(False)
 
1762
                self.JobStorageIDEdit.setEnabled(False)
 
1763
                self.JobStorageIDDefaultButton.setEnabled(False)
 
1764
 
 
1765
                # Duplicate/existing Jobname/ID
 
1766
                self.JobStorageExistingComboBox.setEnabled(False)
 
1767
 
 
1768
            else:
 
1769
                # PIN
 
1770
                if self.job_storage_mode in (JOB_STORAGE_TYPE_PERSONAL, JOB_STORAGE_TYPE_STORE):
 
1771
                    self.JobStoragePinGroupBox.setEnabled(True)
 
1772
                    self.JobStoragePinDefaultButton.setEnabled(self.job_storage_use_pin)
 
1773
                    self.JobStoragePinEdit.setEnabled(self.job_storage_use_pin)
 
1774
                    self.JobStoragePinEdit.setText(str(self.job_storage_pin))
 
1775
                else:
 
1776
                    self.JobStoragePinGroupBox.setEnabled(False)
 
1777
                    self.JobStoragePinEdit.setEnabled(False)
 
1778
                    self.JobStoragePinDefaultButton.setEnabled(False)
 
1779
                    self.JobStoragePinEdit.setText(str())
 
1780
 
 
1781
                # Username
 
1782
                self.JobStorageUsernameGroupBox.setEnabled(True)
 
1783
                self.JobStorageUsernameEdit.setEnabled(not self.job_storage_auto_username)
 
1784
                self.JobStorageUsernameDefaultButton.setEnabled(not self.job_storage_auto_username)
 
1785
                self.JobStorageUsernameEdit.setText(str(self.job_storage_username))
 
1786
 
 
1787
                # Jobname/ID
 
1788
                self.JobStorageIDGroupBox.setEnabled(True)
 
1789
                self.JobStorageIDEdit.setEnabled(not self.job_storage_auto_jobname)
 
1790
                self.JobStorageIDDefaultButton.setEnabled(not self.job_storage_auto_jobname)
 
1791
                self.JobStorageIDEdit.setText(str(self.job_storage_jobname))
 
1792
 
 
1793
                # Duplicate/existing JobName/ID
 
1794
                self.JobStorageExistingComboBox.setEnabled(not self.job_storage_auto_jobname)
 
1795
                self.JobStorageExistingDefaultButton.setEnabled(not self.job_storage_auto_jobname and self.job_storage_job_exist != JOB_STORAGE_EXISTING_JOB_REPLACE)
 
1796
 
 
1797
        finally:
 
1798
            endWaitCursor()
 
1799
 
 
1800
 
 
1801
    def saveJobStorageOptions(self):
 
1802
        beginWaitCursor()
 
1803
        try:
 
1804
            log.debug("Saving job storage options...")
 
1805
 
 
1806
            if self.job_storage_mode == JOB_STORAGE_TYPE_OFF:
 
1807
                log.debug("Job storage mode = JOB_STORAGE_TYPE_OFF")
 
1808
                self.setPrinterOption('HOLD', 'OFF')
 
1809
                self.removePrinterOption('HOLDTYPE')
 
1810
                self.removePrinterOption('USERNAME')
 
1811
                self.removePrinterOption('JOBNAME')
 
1812
                self.removePrinterOption('DUPLICATEJOB')
 
1813
 
 
1814
            elif self.job_storage_mode == JOB_STORAGE_TYPE_PROOF_AND_HOLD:
 
1815
                log.debug("Job storage mode = JOB_STORAGE_TYPE_PROOF_AND_HOLD")
 
1816
                self.setPrinterOption('HOLD', 'PROOF')
 
1817
                #self.removePrinterOption('HOLDTYPE')
 
1818
                self.setPrinterOption('HOLDTYPE', 'PUBLIC')
 
1819
 
 
1820
            elif self.job_storage_mode == JOB_STORAGE_TYPE_PERSONAL:
 
1821
                log.debug("Job storage mode = JOB_STORAGE_TYPE_PERSONAL")
 
1822
 
 
1823
                if self.job_storage_use_pin:
 
1824
                    self.setPrinterOption('HOLD', 'ON')
 
1825
                else:
 
1826
                    self.setPrinterOption('HOLD', 'PROOF')
 
1827
                    self.setPrinterOption('HOLDTYPE', 'PUBLIC')
 
1828
 
 
1829
 
 
1830
            elif self.job_storage_mode == JOB_STORAGE_TYPE_QUICK_COPY:
 
1831
                log.debug("Job storage mode = JOB_STORAGE_TYPE_QUICK_COPY")
 
1832
                self.setPrinterOption('HOLD', 'ON')
 
1833
                self.setPrinterOption('HOLDTYPE', 'PUBLIC')
 
1834
 
 
1835
            elif self.job_storage_mode == JOB_STORAGE_TYPE_STORE:
 
1836
                log.debug("Job storage mode = JOB_STORAGE_TYPE_STORE")
 
1837
                self.setPrinterOption('HOLD', 'STORE')
 
1838
 
 
1839
                if not self.job_storage_use_pin:
 
1840
                    self.removePrinterOption('HOLDTYPE')
 
1841
 
 
1842
            # PIN
 
1843
            log.debug("Job storage use pin = %d" % self.job_storage_use_pin)
 
1844
            if self.job_storage_use_pin:
 
1845
                self.setPrinterOption('HOLDTYPE', 'PRIVATE')
 
1846
 
 
1847
            #else:
 
1848
            #    self.removePrinterOption('HOLDKEY')
 
1849
 
 
1850
            # Dup/exisiting
 
1851
            if self.job_storage_job_exist == JOB_STORAGE_EXISTING_JOB_REPLACE:
 
1852
                log.debug("Job storage duplicate = JOB_STORAGE_EXISTING_JOB_REPLACE")
 
1853
                self.setPrinterOption('DUPLICATEJOB', 'REPLACE')
 
1854
 
 
1855
            else: # JOB_STORAGE_EXISTING_JOB_APPEND_1_99
 
1856
                log.debug("Job storage duplicate = JOB_STORAGE_EXISTING_JOB_APPEND_1_99")
 
1857
                self.setPrinterOption('DUPLICATEJOB', 'APPEND')
 
1858
 
 
1859
 
 
1860
        finally:
 
1861
            endWaitCursor()
 
1862
 
 
1863
 
 
1864
    #
 
1865
    # Mode
 
1866
    #
 
1867
 
 
1868
    def JobStorageModeComboBox_activated(self, i):
 
1869
        sender = self.sender()
 
1870
        mode, ok = value_int(sender.itemData(i))
 
1871
        if ok:
 
1872
            self.job_storage_mode = mode
 
1873
            self.saveJobStorageOptions()
 
1874
            self.updateJobStorageControls()
 
1875
 
 
1876
 
 
1877
    def JobStorageModeDefaultButton_clicked(self):
 
1878
        self.JobStorageModeComboBox.emit(SIGNAL("activated(int)"), JOB_STORAGE_TYPE_OFF)
 
1879
 
 
1880
 
 
1881
    #
 
1882
    # PIN
 
1883
    #
 
1884
 
 
1885
    def JobStoragePinOffRadioButton_toggled(self, b):
 
1886
        self.job_storage_use_pin = not b
 
1887
        self.updateJobStorageControls()
 
1888
        self.saveJobStorageOptions()
 
1889
 
 
1890
 
 
1891
    def JobStoragePinPrivateRadioButton_toggled(self, b):
 
1892
        self.job_storage_use_pin = b
 
1893
        self.updateJobStorageControls()
 
1894
        self.saveJobStorageOptions()
 
1895
 
 
1896
 
 
1897
    def JobStoragePinDefaultButton_clicked(self):
 
1898
        self.JobStoragePinOffRadioButton.emit(SIGNAL("toggled(bool)"), True)
 
1899
 
 
1900
 
 
1901
    def JobStoragePinEdit_textEdited(self, s):
 
1902
        self.job_storage_pin = to_unicode(s)
 
1903
        self.setPrinterOption('HOLDKEY', self.job_storage_pin.encode('ascii'))
 
1904
 
 
1905
 
 
1906
 
 
1907
    #
 
1908
    # Username
 
1909
    #
 
1910
 
 
1911
    def JobStorageUsernameAutoRadioButton_toggled(self, b):
 
1912
        self.job_storage_auto_username = b
 
1913
        self.updateJobStorageControls()
 
1914
        self.saveJobStorageOptions()
 
1915
 
 
1916
 
 
1917
    def JobStorageUsernameCustomRadioButton_toggled(self, b):
 
1918
        self.job_storage_auto_username = not b
 
1919
        self.updateJobStorageControls()
 
1920
        self.saveJobStorageOptions()
 
1921
 
 
1922
 
 
1923
    def JobStorageUsernameDefaultButton_clicked(self):
 
1924
        self.JobStorageUsernameAutoRadioButton.emit(SIGNAL("toggled(bool)"), True)
 
1925
 
 
1926
 
 
1927
    def JobStorageUsernameEdit_textEdited(self, s):
 
1928
        self.job_storage_username = to_unicode(s)
 
1929
        self.setPrinterOption('USERNAME', self.job_storage_username.encode('ascii'))
 
1930
 
 
1931
    #
 
1932
    # Jobname/ID
 
1933
    #
 
1934
 
 
1935
    def JobStorageIDAutoRadioButton_toggled(self, b):
 
1936
        self.job_storage_auto_jobname = b
 
1937
        self.updateJobStorageControls()
 
1938
        self.saveJobStorageOptions()
 
1939
 
 
1940
 
 
1941
    def JobStorageIDCustomRadioButton_toggled(self, b):
 
1942
        self.job_storage_auto_jobname = not b
 
1943
        self.updateJobStorageControls()
 
1944
        self.saveJobStorageOptions()
 
1945
 
 
1946
 
 
1947
    def JobStorageIDDefaultButton_clicked(self):
 
1948
        self.JobStorageIDAutoRadioButton.emit(SIGNAL("toggled(bool)"), True)
 
1949
 
 
1950
 
 
1951
    def JobStorageIDEdit_textEdited(self, s):
 
1952
        self.job_storage_jobname = to_unicode(s)
 
1953
        self.setPrinterOption('JOBNAME', self.job_storage_jobname.encode('ascii'))
 
1954
 
 
1955
    #
 
1956
    # Duplicate/existing Jobname/ID
 
1957
    #
 
1958
 
 
1959
    def JobStorageExistingComboBox_activated(self, i):
 
1960
        sender = self.sender()
 
1961
        opt, ok = value_int(sender.itemData(i))
 
1962
        if ok:
 
1963
            self.job_storage_job_exist = opt
 
1964
            self.updateJobStorageControls()
 
1965
            self.saveJobStorageOptions()
 
1966
 
 
1967
 
 
1968
    def JobStorageExistingDefaultButton_clicked(self):
 
1969
        self.JobStorageExistingComboBox.emit(SIGNAL("activated(int)"), JOB_STORAGE_EXISTING_JOB_REPLACE)
 
1970
 
 
1971
 
 
1972
    #
 
1973
    # Printer I/O
 
1974
    #
 
1975
 
 
1976
    def setPrinterOption(self, option, value):
 
1977
        log.debug("setPrinterOption(%s, %s)" % (option, value))
 
1978
        cups.openPPD(self.cur_printer)
 
1979
 
 
1980
        try:
 
1981
            cups.addOption("%s=%s" % (option, value))
 
1982
            cups.setOptions()
 
1983
        finally:
 
1984
            cups.closePPD()
 
1985
 
 
1986
    def removePrinterOption(self, option):
 
1987
        log.debug("removePrinterOption(%s)" % option)
 
1988
        cups.openPPD(self.cur_printer)
 
1989
 
 
1990
        try:
 
1991
            cups.removeOption(option)
 
1992
            cups.setOptions()
 
1993
        finally:
 
1994
            cups.closePPD()
 
1995
 
 
1996
 
 
1997
    def __tr(self,s,c = None):
 
1998
        return qApp.translate("PrintSettingsToolbox",s,c)
 
1999