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 20# 21 22# Local 23from base.g import * 24from base import utils, pml 25from copier import copier 26from base.sixext.moves import queue 27 28# Qt 29from qt import * 30from .scrollview import ScrollView, PixmapLabelButton 31from .waitform import WaitForm 32 33# Std Lib 34import os.path, os 35 36 37class ScrollCopyView(ScrollView): 38 def __init__(self, service, num_copies=None, contrast=None, quality=None, 39 reduction=None, fit_to_page=None, parent=None, form=None, name=None, fl=0): 40 ScrollView.__init__(self, service, parent, name, fl) 41 42 self.form = form 43 44 self.num_copies = num_copies 45 self.contrast = contrast 46 self.quality = quality 47 self.reduction = reduction 48 self.fit_to_page = fit_to_page 49 50 self.update_queue = queue.Queue() # UI updates from copy thread 51 self.event_queue = queue.Queue() # UI events to copy thread 52 53 def getDeviceSettings(self): 54 QApplication.setOverrideCursor(QApplication.waitCursor) 55 try: 56 # get sticky settings as defaults (if not spec'd on command line) 57 if self.num_copies is None: 58 result_code, self.num_copies = self.dev.getPML(pml.OID_COPIER_NUM_COPIES) 59 60 if self.contrast is None: 61 result_code, self.contrast = self.dev.getPML(pml.OID_COPIER_CONTRAST) 62 63 if self.reduction is None: 64 result_code, self.reduction = self.dev.getPML(pml.OID_COPIER_REDUCTION) 65 66 if self.quality is None: 67 result_code, self.quality = self.dev.getPML(pml.OID_COPIER_QUALITY) 68 69 if self.scan_src == SCAN_SRC_FLATBED and self.fit_to_page is None: 70 result_code, self.fit_to_page = self.dev.getPML(pml.OID_COPIER_FIT_TO_PAGE) 71 72 if result_code != pml.ERROR_OK: 73 self.fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED 74 self.fitToPageCheckBox.setEnabled(False) 75 76 else: 77 self.fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED 78 79 if self.scan_src != SCAN_SRC_FLATBED: 80 self.fitToPageCheckBox.setEnabled(False) 81 82 result_code, self.max_reduction = self.dev.getPML(pml.OID_COPIER_REDUCTION_MAXIMUM) 83 result_code, self.max_enlargement = self.dev.getPML(pml.OID_COPIER_ENLARGEMENT_MAXIMUM) 84 85 # contrast 86 a = self.contrast/25 87 self.contrastSpinBox.setValue(a) 88 89 if a >= 0: 90 self.contrastSpinBox.setPrefix("+") 91 else: 92 self.contrastSpinBox.setPrefix("") 93 94 self.contrastSlider.setValue(a) 95 self.contrastSlider.setTickmarks(QSlider.Below) 96 self.contrastSlider.setTickInterval(1) 97 98 self.contrastDefaultPushButton.setEnabled(a != 0) 99 100 # reduction/enlargement/fittopage 101 102 self.reductionSlider.setRange(self.max_reduction, self.max_enlargement) 103 self.reductionSlider.setTickmarks(QSlider.Below) 104 self.reductionSlider.setTickInterval(10) 105 self.reductionSlider.setValue(self.reduction) 106 107 self.reductionSpinBox.setMaxValue(self.max_enlargement) 108 self.reductionSpinBox.setMinValue(self.max_reduction) 109 self.reductionSpinBox.setValue(self.reduction) 110 self.reductionSpinBox.setSuffix("%") 111 112 if self.fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED: 113 self.fitToPageCheckBox.setChecked(True) 114 self.reductionSpinBox.setEnabled(False) 115 self.reductionSlider.setEnabled(False) 116 self.reductionDefaultPushButton.setEnabled(True) 117 else: 118 self.fitToPageCheckBox.setChecked(False) 119 self.reductionSlider.setEnabled(True) 120 self.reductionSpinBox.setEnabled(True) 121 self.reductionDefaultPushButton.setEnabled(self.reduction != 100) 122 123 # num_copies 124 self.copiesSpinBox.setValue(self.num_copies) 125 self.copiesDefaultPushButton.setEnabled(self.num_copies != 1) 126 127 # quality 128 if self.quality == pml.COPIER_QUALITY_FAST: 129 self.qualityComboBox.setCurrentItem(0) 130 s = 'Fast' 131 132 elif self.quality == pml.COPIER_QUALITY_DRAFT: 133 self.qualityComboBox.setCurrentItem(1) 134 s = 'Draft' 135 136 elif self.quality == pml.COPIER_QUALITY_NORMAL: 137 self.qualityComboBox.setCurrentItem(2) 138 s = 'Normal' 139 140 elif self.quality == pml.COPIER_QUALITY_PRESENTATION: 141 self.qualityComboBox.setCurrentItem(3) 142 s = 'Presentation' 143 144 elif self.quality == pml.COPIER_QUALITY_BEST: 145 self.qualityComboBox.setCurrentItem(4) 146 s = 'Best' 147 148 log.debug("Default Quality: %d (%s)" % (self.quality, s)) 149 150 self.qualityDefaultPushButton.setEnabled(self.quality != pml.COPIER_QUALITY_NORMAL) 151 152 log.debug("Default Num copies: %d" % self.num_copies) 153 log.debug("Default Contrast: %d" % self.contrast) 154 log.debug("Default Reduction: %d" % self.reduction) 155 log.debug("Maximum Reduction: %d" % self.max_reduction) 156 log.debug("Maximum Enlargement: %d" % self.max_enlargement) 157 158 if self.fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED: 159 s = 'Enabled' # 2 160 else: 161 s = 'Disabled' # 1 162 163 log.debug("Default Fit to page: %s (%s)" % (self.fit_to_page, s)) 164 log.debug("Scan src (models.dat: scan-src): %d" % self.scan_src) 165 166 finally: 167 self.dev.closePML() 168 QApplication.restoreOverrideCursor() 169 170 171 def fillControls(self): 172 ScrollView.fillControls(self) 173 174 self.addGroupHeading("copies", self.__tr("Number of Copies")) 175 self.addCopies() 176 177 self.addGroupHeading("reduction", self.__tr("Enlargement, Reduction and Fit to Page")) 178 self.addEnlargementReduction() 179 180 self.addGroupHeading("contrast", self.__tr("Copy Contrast")) 181 self.addContrast() 182 183 self.addGroupHeading("quality", self.__tr("Copy Quality")) 184 self.addQuality() 185 186 self.addGroupHeading("space1", "") 187 188 self.copyButton = self.addActionButton("bottom_nav", self.__tr("Make Copies(s)"), 189 self.copyButton_clicked, 'print.png', 'print.png', 190 self.__tr("Close"), self.funcButton_clicked) 191 192 193 194 def onUpdate(self, cur_device=None): 195 log.debug("ScrollPrintView.onUpdate()") 196 197 def onDeviceChange(self, cur_device=None): 198 ScrollView.onDeviceChange(self, cur_device) 199 200 self.dev = copier.PMLCopyDevice(device_uri=self.cur_device.device_uri, 201 printer_name=self.cur_printer) 202 203 self.scan_src = self.dev.mq.get('scan-src', SCAN_SRC_FLATBED) 204 self.copy_type = self.dev.mq.get('copy-type', COPY_TYPE_DEVICE) 205 206 if self.scan_src == SCAN_SRC_SCROLLFED: 207 self.fitToPageCheckBox.setEnabled(False) 208 self.fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED 209 210 self.getDeviceSettings() 211 212 213 def addCopies(self): 214 widget = self.getWidget() 215 216 layout12 = QHBoxLayout(widget,5,10,"layout12") 217 218 self.textLabel5 = QLabel(widget,"textLabel5") 219 layout12.addWidget(self.textLabel5) 220 spacer20 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) 221 layout12.addItem(spacer20) 222 223 self.copiesSpinBox = QSpinBox(widget,"copiesSpinBox") 224 layout12.addWidget(self.copiesSpinBox) 225 226 self.copiesDefaultPushButton = QPushButton(widget,"copiesDefaultPushButton") 227 layout12.addWidget(self.copiesDefaultPushButton) 228 229 self.textLabel5.setText(self.__tr("Number of copies:")) 230 self.copiesDefaultPushButton.setText(self.__tr("Default")) 231 232 self.copiesSpinBox.setMaxValue(99) 233 self.copiesSpinBox.setMinValue(1) 234 self.copiesSpinBox.setValue(1) 235 236 self.copiesDefaultPushButton.setEnabled(False) 237 238 self.connect(self.copiesDefaultPushButton, SIGNAL("clicked()"), self.copiesDefaultPushButton_clicked) 239 self.connect(self.copiesSpinBox, SIGNAL("valueChanged(int)"), self.copiesSpinBox_valueChanged) 240 241 self.addWidget(widget, "copies") 242 243 def copiesDefaultPushButton_clicked(self): 244 self.copiesSpinBox.setValue(1) 245 self.copiesDefaultPushButton.setEnabled(False) 246 247 def copiesSpinBox_valueChanged(self, i): 248 self.copiesDefaultPushButton.setEnabled(i != 1) 249 self.num_copies = i 250 251 def addQuality(self): 252 widget = self.getWidget() 253 layout34 = QHBoxLayout(widget,5,10,"layout34") 254 255 self.textLabel5_4 = QLabel(widget,"textLabel5_4") 256 self.textLabel5_4.setText(self.__tr("Quality:")) 257 layout34.addWidget(self.textLabel5_4) 258 259 spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) 260 layout34.addItem(spacer20_4) 261 262 self.qualityComboBox = QComboBox(0,widget,"qualityComboBox") 263 layout34.addWidget(self.qualityComboBox) 264 265 self.qualityDefaultPushButton = QPushButton(widget,"qualityDefaultPushButton") 266 layout34.addWidget(self.qualityDefaultPushButton) 267 268 self.qualityComboBox.clear() 269 self.qualityComboBox.insertItem(self.__tr("Fast")) # 0 270 self.qualityComboBox.insertItem(self.__tr("Draft")) # 1 271 self.qualityComboBox.insertItem(self.__tr("Normal")) # 2 272 self.qualityComboBox.insertItem(self.__tr("Presentation")) # 3 273 self.qualityComboBox.insertItem(self.__tr("Best")) # 4 274 self.qualityComboBox.setCurrentItem(2) # Normal 275 276 self.qualityDefaultPushButton.setText(self.__tr("Default")) 277 self.qualityDefaultPushButton.setEnabled(False) 278 279 self.connect(self.qualityComboBox, SIGNAL("activated(int)"), self.qualityComboBox_activated) 280 self.connect(self.qualityDefaultPushButton, SIGNAL("clicked()"), self.qualityDefaultPushButton_clicked) 281 282 self.addWidget(widget, "quality") 283 284 def qualityDefaultPushButton_clicked(self): 285 self.qualityDefaultPushButton.setEnabled(False) 286 self.qualityComboBox.setCurrentItem(2) # Normal 287 self.quality = pml.COPIER_QUALITY_NORMAL 288 289 def qualityComboBox_activated(self, i): 290 self.qualityDefaultPushButton.setEnabled(i != 2) # Normal 291 292 if i == 0: 293 self.quality = pml.COPIER_QUALITY_FAST 294 elif i == 1: 295 self.quality = pml.COPIER_QUALITY_DRAFT 296 elif i == 2: 297 self.quality = pml.COPIER_QUALITY_NORMAL 298 elif i == 3: 299 self.quality = pml.COPIER_QUALITY_PRESENTATION 300 elif i == 4: 301 self.quality = pml.COPIER_QUALITY_BEST 302 303 304 def addEnlargementReduction(self): 305 widget = self.getWidget() 306 layout43 = QGridLayout(widget,1,1,5,10,"layout43") 307 308 self.reductionSlider = QSlider(widget,"reductionSlider") 309 self.reductionSlider.setOrientation(QSlider.Horizontal) 310 311 layout43.addWidget(self.reductionSlider,0,2) 312 313 self.reductionSpinBox = QSpinBox(widget, "reductionSpinBox") 314 self.reductionSpinBox.setMaxValue(100) 315 self.reductionSpinBox.setMinValue(0) 316 self.reductionSpinBox.setValue(100) 317 self.reductionSpinBox.setSuffix("%") 318 layout43.addWidget(self.reductionSpinBox,0,3) 319 320 spacer42 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) 321 layout43.addItem(spacer42,0,1) 322 323 self.fitToPageCheckBox = QCheckBox(widget,"fitToPageCheckBox") 324 layout43.addWidget(self.fitToPageCheckBox,1,2) 325 326 self.reductionDefaultPushButton = QPushButton(widget,"reductionDefaultPushButton") 327 layout43.addWidget(self.reductionDefaultPushButton,0,4) 328 329 self.textLabel1 = QLabel(widget,"textLabel1") 330 layout43.addWidget(self.textLabel1,0,0) 331 332 self.textLabel1.setText(self.__tr("Enlargement or reduction (percent):")) 333 self.fitToPageCheckBox.setText(self.__tr("Fit to Page")) 334 self.reductionDefaultPushButton.setText(self.__tr("Default")) 335 336 self.reductionSlider.setRange(25, 400) 337 338 self.connect(self.reductionSlider,SIGNAL("valueChanged(int)"),self.reductionSlider_valueChanged) 339 self.connect(self.fitToPageCheckBox,SIGNAL("clicked()"),self.fitToPageCheckBox_clicked) 340 self.connect(self.reductionDefaultPushButton, SIGNAL("clicked()"), self.reductionDefaultPushButton_clicked) 341 self.connect(self.reductionSpinBox, SIGNAL("valueChanged(int)"), self.reductionSpinBox_valueChanged) 342 343 self.addWidget(widget, "reduction") 344 345 def reductionSlider_valueChanged(self,a0): 346 self.reduction = a0 347 self.reductionSpinBox.setValue(a0) 348 self.reductionDefaultPushButton.setEnabled(a0 != 100) 349 350 def reductionSpinBox_valueChanged(self, a0): 351 self.reduction = a0 352 self.reductionSlider.setValue(a0) 353 self.reductionDefaultPushButton.setEnabled(a0 != 100) 354 355 def fitToPageCheckBox_clicked(self): 356 if self.fitToPageCheckBox.isChecked(): 357 self.fit_to_page = pml.COPIER_FIT_TO_PAGE_ENABLED 358 self.reductionSpinBox.setEnabled(False) 359 self.reductionSlider.setEnabled(False) 360 self.reductionDefaultPushButton.setEnabled(True) 361 else: 362 self.fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED 363 self.reductionSlider.setEnabled(True) 364 self.reductionSpinBox.setEnabled(True) 365 self.reductionDefaultPushButton.setEnabled(self.reductionSlider.value() != 100) 366 367 def reductionDefaultPushButton_clicked(self): 368 self.reduction = 100 369 self.reductionSlider.setValue(100) 370 self.reductionSlider.setEnabled(True) 371 self.reductionSpinBox.setValue(100) 372 self.reductionSpinBox.setEnabled(True) 373 self.fitToPageCheckBox.setChecked(False) 374 self.fit_to_page = False 375 376 def addContrast(self): 377 widget = self.getWidget() 378 379 layout41 = QGridLayout(widget,1,1,5,10,"layout41") 380 381 self.textLabel1_2 = QLabel(widget,"textLabel1_2") 382 383 layout41.addWidget(self.textLabel1_2,0,0) 384 385 self.contrastDefaultPushButton = QPushButton(widget,"contrastDefaultPushButton") 386 387 layout41.addWidget(self.contrastDefaultPushButton,0,4) 388 spacer41 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) 389 layout41.addItem(spacer41,0,1) 390 391 self.contrastSlider = QSlider(widget,"contrastSlider") 392 self.contrastSlider.setMinValue(-5) 393 self.contrastSlider.setMaxValue(5) 394 self.contrastSlider.setPageStep(1) 395 self.contrastSlider.setOrientation(QSlider.Horizontal) 396 397 layout41.addWidget(self.contrastSlider,0,2) 398 399 self.contrastSpinBox = QSpinBox(widget, "contrastSpinBox") 400 self.contrastSpinBox.setMinValue(-5) 401 self.contrastSpinBox.setMaxValue(5) 402 403 layout41.addWidget(self.contrastSpinBox,0,3) 404 405 self.textLabel1_2.setText(self.__tr("Contrast (-5 lighter to +5 darker):")) 406 self.contrastDefaultPushButton.setText(self.__tr("Default")) 407 408 self.connect(self.contrastSlider,SIGNAL("valueChanged(int)"),self.contrastSlider_valueChanged) 409 self.connect(self.contrastSpinBox, SIGNAL("valueChanged(int)"), self.contrastSpinBox_valueChanged) 410 self.connect(self.contrastDefaultPushButton, SIGNAL("clicked()"), self.contrastDefaultPushButton_clicked) 411 412 self.addWidget(widget, "contrast") 413 414 415 def contrastSlider_valueChanged(self, a0): 416 self.contrastSpinBox.setValue(a0) 417 self.contrast = a0 * 25 418 self.contrastDefaultPushButton.setEnabled(a0 != 0) 419 420 def contrastSpinBox_valueChanged(self, a0): 421 if a0 >= 0: 422 self.contrastSpinBox.setPrefix("+") 423 else: 424 self.contrastSpinBox.setPrefix("") 425 426 self.contrastSlider.setValue(a0) 427 self.contrast = a0 * 25 428 self.contrastDefaultPushButton.setEnabled(a0 != 0) 429 430 def contrastDefaultPushButton_clicked(self): 431 self.contrastSpinBox.setValue(0) 432 self.contrastSpinBox.setPrefix("+") 433 self.contrastSlider.setValue(0) 434 self.contrast = 0 435 436 437 def copy_canceled(self): 438 self.event_queue.put(copier.COPY_CANCELED) 439 self.dev.sendEvent(EVENT_COPY_JOB_CANCELED) 440 441 def copy_timer_timeout(self): 442 while self.update_queue.qsize(): 443 try: 444 status = self.update_queue.get(0) 445 except queue.Empty: 446 break 447 448 if status == copier.STATUS_IDLE: 449 self.copy_timer.stop() 450 451 #self.pb.hide() 452 #self.form.statusBar().removeWidget(self.pb) 453 454 elif status in (copier.STATUS_SETTING_UP, copier.STATUS_WARMING_UP): 455 #self.pb.setProgress(self.pb.progress()+1) 456 pass 457 458 elif status == copier.STATUS_ACTIVE: 459 #self.pb.setProgress(self.pb.progress()+1) 460 pass 461 462 elif status in (copier.STATUS_ERROR, copier.STATUS_DONE): 463 self.copy_timer.stop() 464 #self.pb.hide() 465 #self.form.statusBar().removeWidget(self.pb) 466 467 # Close the dialog box. 468 # 469 if self.waitdlg is not None: 470 self.waitdlg.hide() 471 self.waitdlg.close() 472 self.waitdlg = None 473 474 if status == copier.STATUS_ERROR: 475 self.form.FailureUI(self.__tr("<b>Copier error.</b><p>")) 476 self.dev.sendEvent(EVENT_COPY_JOB_FAIL) 477 478 elif status == copier.STATUS_DONE: 479 pass 480 self.dev.sendEvent(EVENT_END_COPY_JOB) 481 482 self.cur_device.close() 483 self.copyButton.setEnabled(True) 484 485 self.form.close() 486 487 488 def copyButton_clicked(self): 489 self.copyButton.setEnabled(False) 490 try: 491 try: 492 self.dev.open() 493 except Error: 494 self.form.FailureUI(self.__tr("<b>Cannot copy: Device is busy or not available.</b><p>Please check device and try again. [1]")) 495 return 496 497 self.dev.sendEvent(EVENT_START_COPY_JOB, self.cur_printer, 0, '') 498 #self.pb = QProgressBar() 499 #self.pb.setTotalSteps(2) 500 #self.form.statusBar().addWidget(self.pb) 501 #self.pb.show() 502 503 log.debug("Num copies: %d" % self.num_copies) 504 log.debug("Contrast: %d" % self.contrast) 505 log.debug("Reduction: %d" % self.reduction) 506 507 s = 'Normal' 508 if self.quality == pml.COPIER_QUALITY_FAST: 509 s = 'Fast' 510 elif self.quality == pml.COPIER_QUALITY_DRAFT: 511 s = 'Draft' 512 elif self.quality == pml.COPIER_QUALITY_NORMAL: 513 s = 'Normal' 514 elif self.quality == pml.COPIER_QUALITY_PRESENTATION: 515 s = 'Presentation' 516 elif self.quality == pml.COPIER_QUALITY_BEST: 517 s = 'Best' 518 519 log.debug("Quality: %d (%s)" % (self.quality, s)) 520 521 if self.fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED: 522 s = 'Enabled' # 2 523 else: 524 s = 'Disabled' # 1 525 526 log.debug("Fit to page: %s (%s)" % (self.fit_to_page, s)) 527 log.debug("Scan src: %d" % self.scan_src) 528 529 # Open the dialog box. 530 # 531 self.waitdlg = WaitForm(0, self.__tr("Copying..."), self.copy_canceled, self, modal=1) 532 self.waitdlg.show() 533 534 self.copy_timer = QTimer(self, "CopyTimer") 535 self.connect(self.copy_timer, SIGNAL('timeout()'), self.copy_timer_timeout) 536 self.copy_timer.start(1000) # 1 sec UI updates 537 538 self.dev.copy(self.num_copies, self.contrast, self.reduction, 539 self.quality, self.fit_to_page, self.scan_src, 540 self.update_queue, self.event_queue) 541 542 finally: 543 #self.cur_device.close() 544 #self.copyButton.setEnabled(True) 545 pass 546 547 def funcButton_clicked(self): 548 self.dev.close() 549 self.form.close() 550 551 def __tr(self,s,c = None): 552 return qApp.translate("ScrollCopy",s,c) 553