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