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