Tizen 2.1 base
[platform/upstream/hplip.git] / makecopies.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # Author: Don Welch
21 #
22
23 __version__ = '4.0'
24 __title__ = "Make Copies Utility"
25 __mod__ = 'hp-makecopies'
26 __doc__ = "PC initiated make copies function on supported HP AiO and MFP devices. (Note: Currently unsupported in Qt4.)"
27
28 # Std Lib
29 import sys
30 import os
31 import getopt
32 import re
33 import Queue
34 import time
35 import operator
36
37 # Local
38 from base.g import *
39 from base import utils, device, pml, tui, module
40 from copier import copier
41 from prnt import cups
42
43
44 mod = module.Module(__mod__, __title__, __version__, __doc__, None,
45                     (NON_INTERACTIVE_MODE, GUI_MODE),
46                     (UI_TOOLKIT_QT3, UI_TOOLKIT_QT4))
47
48 mod.setUsage(module.USAGE_FLAG_DEVICE_ARGS,
49     extra_options=[
50     ("Number of copies:", "-m<num_copies> or --copies=<num_copies> or --num=<num_copies> (1-99)", "option", False),
51     ("Reduction/enlargement:", "-r<%> or --reduction=<%> or --enlargement=<%> (25-400%)", "option", False),
52      ("Quality:", "-q<quality> or --quality=<quality> (where quality is: 'fast', 'draft', 'normal', 'presentation', or 'best')", "option", False),
53      ("Contrast:", "-c<contrast> or --contrast=<contrast> (-5 to +5)", "option", False),
54      ("Fit to page (flatbed only):", "-f or --fittopage or --fit (overrides reduction/enlargement)", "option", False)])
55
56 opts, device_uri, printer_name, mode, ui_toolkit, loc = \
57     mod.parseStdOpts('m:r:q:c:f',
58                      ['num=', 'copies=', 'reduction=', 'enlargement=', 'quality=',
59                       'contrast=', 'fittopage', 'fit', 'fit-to-page'])
60
61 device_uri = mod.getDeviceUri(device_uri, printer_name,
62     filter={'copy-type': (operator.gt, 0)})
63
64 num_copies = None
65 reduction = None
66 reduction_spec = False
67 contrast = None
68 quality = None
69 fit_to_page = None
70
71
72 for o, a in opts:
73     if o in ('-m', '--num', '--copies'):
74         try:
75             num_copies = int(a)
76         except ValueError:
77             log.warning("Invalid number of copies. Set to default of 1.")
78             num_copies = 1
79
80         if num_copies < 1:
81             log.warning("Invalid number of copies. Set to minimum of 1.")
82             num_copies = 1
83
84         elif num_copies > 99:
85             log.warning("Invalid number of copies. Set to maximum of 99.")
86             num_copies = 99
87
88     elif o in ('-c', '--contrast'):
89         try:
90             contrast = int(a)
91         except ValueError:
92             log.warning("Invalid contrast setting. Set to default of 0.")
93             contrast = 0
94
95         if contrast < -5:
96             log.warning("Invalid contrast setting. Set to minimum of -5.")
97             contrast = -5
98
99         elif contrast > 5:
100             log.warning("Invalid contrast setting. Set to maximum of +5.")
101             contrast = 5
102
103         contrast *= 25
104
105     elif o in ('-q', '--quality'):
106         a = a.lower().strip()
107
108         if a == 'fast':
109             quality = pml.COPIER_QUALITY_FAST
110
111         elif a.startswith('norm'):
112             quality = pml.COPIER_QUALITY_NORMAL
113
114         elif a.startswith('pres'):
115             quality = pml.COPIER_QUALITY_PRESENTATION
116
117         elif a.startswith('draf'):
118             quality = pml.COPIER_QUALITY_DRAFT
119
120         elif a == 'best':
121             quality = pml.COPIER_QUALITY_BEST
122
123         else:
124             log.warning("Invalid quality. Set to default of 'normal'.")
125
126     elif o in ('-r', '--reduction', '--enlargement'):
127         reduction_spec = True
128         try:
129             reduction = int(a.replace('%', ''))
130         except ValueError:
131             log.warning("Invalid reduction %. Set to default of 100%.")
132             reduction = 100
133
134         if reduction < 25:
135             log.warning("Invalid reduction %. Set to minimum of 25%.")
136             reduction = 25
137
138         elif reduction > 400:
139             log.warning("Invalid reduction %. Set to maximum of 400%.")
140             reduction = 400
141
142     elif o in ('-f', '--fittopage', '--fit', '--fit-to-page'):
143         fit_to_page = pml.COPIER_FIT_TO_PAGE_ENABLED
144
145
146
147 if fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED and reduction_spec:
148     log.warning("Fit to page specfied: Reduction/enlargement parameter ignored.")
149
150
151 if mode == GUI_MODE:
152     if ui_toolkit == 'qt3':
153         if not utils.canEnterGUIMode():
154             log.error("%s requires GUI support (try running with --qt4). Also, try using non-interactive (-n) mode." % __mod__)
155             sys.exit(1)
156     else:
157         if not utils.canEnterGUIMode4():
158             log.error("%s requires GUI support (try running with --qt3). Also, try using non-interactive (-n) mode." % __mod__)
159             sys.exit(1)
160
161
162 if mode == GUI_MODE:
163     if ui_toolkit == 'qt3':
164         app = None
165         makecopiesdlg = None
166
167         try:
168             from qt import *
169             from ui.makecopiesform import MakeCopiesForm
170         except ImportError:
171             log.error("Unable to load Qt3 support. Is it installed?")
172             sys.exit(1)
173
174         # create the main application object
175         app = QApplication(sys.argv)
176
177         if loc is None:
178             loc = user_conf.get('ui', 'loc', 'system')
179             if loc.lower() == 'system':
180                 loc = str(QTextCodec.locale())
181                 log.debug("Using system locale: %s" % loc)
182
183         if loc.lower() != 'c':
184             e = 'utf8'
185             try:
186                 l, x = loc.split('.')
187                 loc = '.'.join([l, e])
188             except ValueError:
189                 l = loc
190                 loc = '.'.join([loc, e])
191
192             log.debug("Trying to load .qm file for %s locale." % loc)
193             trans = QTranslator(None)
194
195             qm_file = 'hplip_%s.qm' % l
196             log.debug("Name of .qm file: %s" % qm_file)
197             loaded = trans.load(qm_file, prop.localization_dir)
198
199             if loaded:
200                 app.installTranslator(trans)
201             else:
202                 loc = 'c'
203
204         if loc == 'c':
205             log.debug("Using default 'C' locale")
206         else:
207             log.debug("Using locale: %s" % loc)
208             QLocale.setDefault(QLocale(loc))
209             prop.locale = loc
210             try:
211                 locale.setlocale(locale.LC_ALL, locale.normalize(loc))
212             except locale.Error:
213                 pass
214
215         bus = ['cups']
216         makecopiesdlg = MakeCopiesForm(bus, device_uri, printer_name,
217                                        num_copies, contrast, quality,
218                                        reduction, fit_to_page)
219
220         makecopiesdlg.show()
221         app.setMainWidget(makecopiesdlg)
222
223         try:
224             log.debug("Starting GUI loop...")
225             app.exec_loop()
226         except KeyboardInterrupt:
227             pass
228
229     else: # qt4
230         try:
231             from PyQt4.QtGui import QApplication
232             from ui4.makecopiesdialog import MakeCopiesDialog
233         except ImportError:
234             log.error("Unable to load Qt4 support. Is it installed?")
235             sys.exit(1)
236
237         #try:
238         if 1:
239             app = QApplication(sys.argv)
240
241             dlg = MakeCopiesDialog(None, device_uri)
242             dlg.show()
243             try:
244                 log.debug("Starting GUI loop...")
245                 app.exec_()
246             except KeyboardInterrupt:
247                 sys.exit(0)
248
249         #finally:
250         if 1:
251             sys.exit(0)
252
253
254 else: # NON_INTERACTIVE_MODE
255     try:
256         dev = copier.PMLCopyDevice(device_uri, printer_name)
257
258         try:
259             try:
260                 dev.open()
261
262                 if num_copies is None:
263                     result_code, num_copies = dev.getPML(pml.OID_COPIER_NUM_COPIES)
264
265                 if contrast is None:
266                     result_code, contrast = dev.getPML(pml.OID_COPIER_CONTRAST)
267
268                 if reduction is None:
269                     result_code, reduction = dev.getPML(pml.OID_COPIER_REDUCTION)
270
271                 if quality is None:
272                     result_code, quality = dev.getPML(pml.OID_COPIER_QUALITY)
273
274                 if fit_to_page is None and dev.copy_type == COPY_TYPE_DEVICE:
275                     result_code, fit_to_page = dev.getPML(pml.OID_COPIER_FIT_TO_PAGE)
276                 else:
277                     fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED
278
279                 result_code, max_reduction = dev.getPML(pml.OID_COPIER_REDUCTION_MAXIMUM)
280                 result_code, max_enlargement = dev.getPML(pml.OID_COPIER_ENLARGEMENT_MAXIMUM)
281
282             except Error, e:
283                 log.error(e.msg)
284                 sys.exit(1)
285
286             scan_src = dev.mq.get('scan-src', SCAN_SRC_FLATBED)
287             log.debug(scan_src)
288
289             if scan_src == SCAN_SRC_SCROLLFED:
290                 fit_to_page = pml.COPIER_FIT_TO_PAGE_DISABLED
291
292             log.debug("num_copies = %d" % num_copies)
293             log.debug("contrast= %d" % contrast)
294             log.debug("reduction = %d" % reduction)
295             log.debug("quality = %d" % quality)
296             log.debug("fit_to_page = %d" % fit_to_page)
297             log.debug("max_reduction = %d" % max_reduction)
298             log.debug("max_enlargement = %d" % max_enlargement)
299             log.debug("scan_src = %d" % scan_src)
300
301             update_queue = Queue.Queue()
302             event_queue = Queue.Queue()
303
304             dev.copy(num_copies, contrast, reduction,
305                      quality, fit_to_page, scan_src,
306                      update_queue, event_queue)
307
308
309             cont = True
310             while cont:
311                 while update_queue.qsize():
312                     try:
313                         status = update_queue.get(0)
314                     except Queue.Empty:
315                         break
316
317                     if status == copier.STATUS_IDLE:
318                         log.debug("Idle")
319                         continue
320
321                     elif status in (copier.STATUS_SETTING_UP, copier.STATUS_WARMING_UP):
322                         log.info("Warming up...")
323                         continue
324
325                     elif status == copier.STATUS_ACTIVE:
326                         log.info("Copying...")
327                         continue
328
329                     elif status in (copier.STATUS_ERROR, copier.STATUS_DONE):
330
331                         if status == copier.STATUS_ERROR:
332                             log.error("Copier error!")
333                             dev.sendEvent(EVENT_COPY_JOB_FAIL)
334                             cont = False
335                             break
336
337                         elif status == copier.STATUS_DONE:
338                             cont = False
339                             break
340
341                 time.sleep(2)
342
343         finally:
344             dev.close()
345
346     except KeyboardInterrupt:
347         log.error("User interrupt. Canceling...")
348         event_queue.put(copier.COPY_CANCELED)
349         dev.sendEvent(EVENT_COPY_JOB_CANCELED)
350
351     dev.waitForCopyThread()
352     dev.sendEvent(EVENT_END_COPY_JOB)
353     log.info("")
354     log.info("Done.")
355