Tizen 2.1 base
[platform/upstream/hplip.git] / ui / scrollcopy.py
1 # -*- coding: utf-8 -*-
2 #
3 # (c) Copyright 2001-2007 Hewlett-Packard Development Company, L.P.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # Author: Don Welch
20 #
21
22 # Local
23 from base.g import *
24 from base import utils, pml
25 from copier import copier
26
27 # Qt
28 from qt import *
29 from scrollview import ScrollView, PixmapLabelButton
30 from waitform import WaitForm
31
32 # Std Lib
33 import os.path, os
34 import Queue
35
36
37 class 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)