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