1 # -*- coding: utf-8 -*-
3 # (c) Copyright 2001-2009 Hewlett-Packard Development Company, L.P.
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.
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.
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
24 from base import utils, magic
26 from ui_utils import load_pixmap
30 from scrollview import ScrollView, PixmapLabelButton
31 from allowabletypesdlg import AllowableTypesDlg
32 from jobstoragemixin import JobStorageMixin
39 class RangeValidator(QValidator):
40 def __init__(self, parent=None, name=None):
41 QValidator.__init__(self, parent, name)
43 def validate(self, input, pos):
44 for x in unicode(input)[pos-1:]:
45 if x not in u'0123456789,- ':
46 return QValidator.Invalid, pos
48 return QValidator.Acceptable, pos
52 class FileListViewItem(QListViewItem):
53 def __init__(self, parent, index, filename, mime_type_desc, path):
54 QListViewItem.__init__(self, parent, str(index+1), filename, mime_type_desc, path)
59 class ScrollPrintView(ScrollView):
60 utils.mixin(JobStorageMixin)
62 def __init__(self, service, parent=None, form=None, name=None, fl=0):
63 ScrollView.__init__(self, service, parent, name, fl)
69 self.pages_button_group = 0
70 self.prev_selected_file_index = 0
72 self.allowable_mime_types = cups.getAllowableMIMETypes()
73 log.debug(self.allowable_mime_types)
75 self.MIME_TYPES_DESC = \
77 "application/pdf" : (self.__tr("PDF Document"), '.pdf'),
78 "application/postscript" : (self.__tr("Postscript Document"), '.ps'),
79 "application/vnd.hp-HPGL" : (self.__tr("HP Graphics Language File"), '.hgl, .hpg, .plt, .prn'),
80 "application/x-cshell" : (self.__tr("C Shell Script"), '.csh, .sh'),
81 "application/x-csource" : (self.__tr("C Source Code"), '.c'),
82 "text/cpp": (self.__tr("C/C++ Source Code"), '.c, .cpp, .cxx'),
83 "application/x-perl" : (self.__tr("Perl Script"), '.pl'),
84 "application/x-python" : (self.__tr("Python Program"), '.py'),
85 "application/x-shell" : (self.__tr("Shell Script"), '.sh'),
86 "application/x-sh" : (self.__tr("Shell Script"), '.sh'),
87 "text/plain" : (self.__tr("Plain Text"), '.txt, .log, etc'),
88 "text/html" : (self.__tr("HTML Dcoument"), '.htm, .html'),
89 "image/gif" : (self.__tr("GIF Image"), '.gif'),
90 "image/png" : (self.__tr("PNG Image"), '.png'),
91 "image/jpeg" : (self.__tr("JPEG Image"), '.jpg, .jpeg'),
92 "image/tiff" : (self.__tr("TIFF Image"), '.tif, .tiff'),
93 "image/x-bitmap" : (self.__tr("Bitmap (BMP) Image"), '.bmp'),
94 "image/x-bmp" : (self.__tr("Bitmap (BMP) Image"), '.bmp'),
95 "image/x-photocd" : (self.__tr("Photo CD Image"), '.pcd'),
96 "image/x-portable-anymap" : (self.__tr("Portable Image (PNM)"), '.pnm'),
97 "image/x-portable-bitmap" : (self.__tr("Portable B&W Image (PBM)"), '.pbm'),
98 "image/x-portable-graymap" : (self.__tr("Portable Grayscale Image (PGM)"), '.pgm'),
99 "image/x-portable-pixmap" : (self.__tr("Portable Color Image (PPM)"), '.ppm'),
100 "image/x-sgi-rgb" : (self.__tr("SGI RGB"), '.rgb'),
101 "image/x-xbitmap" : (self.__tr("X11 Bitmap (XBM)"), '.xbm'),
102 "image/x-xpixmap" : (self.__tr("X11 Pixmap (XPM)"), '.xpm'),
103 "image/x-sun-raster" : (self.__tr("Sun Raster Format"), '.ras'),
107 def fillControls(self):
108 ScrollView.fillControls(self)
110 if self.addPrinterFaxList():
111 self.addGroupHeading("files_to_print", self.__tr("File(s) to Print"))
113 self.addGroupHeading("options", self.__tr("Print Options"))
118 self.job_storage_avail = self.cur_device.mq['job-storage'] == JOB_STORAGE_ENABLE
120 if self.job_storage_avail:
121 self.addGroupHeading("jobstorage", self.__tr("Job Storage and Secure Printing"))
124 self.addGroupHeading("space1", "")
126 self.printButton = self.addActionButton("bottom_nav", self.__tr("Print File(s)"),
127 self.printButton_clicked, 'print.png', 'print.png',
128 self.__tr("Close"), self.funcButton_clicked)
130 self.printButton.setEnabled(False)
131 self.maximizeControl()
134 QApplication.restoreOverrideCursor()
135 self.form.FailureUI("<b>Print is disabled.</b><p>No CUPS print queue found for this device.")
136 self.funcButton_clicked()
139 def onUpdate(self, cur_device=None):
140 log.debug("ScrollPrintView.onUpdate()")
141 self.updateFileList()
143 def onDeviceChange(self, cur_device=None):
145 ScrollView.onDeviceChange(self, cur_device)
147 def addFileList(self):
148 widget = self.getWidget()
149 layout37 = QGridLayout(widget,1,1,5,10,"layout37")
151 self.addFilePushButton = PixmapLabelButton(widget,
152 "list_add.png", "list_add.png")
154 layout37.addWidget(self.addFilePushButton,2,0)
156 self.removeFilePushButton = PixmapLabelButton(widget,
157 "list_remove.png", "list_remove.png")
159 layout37.addWidget(self.removeFilePushButton,2,1)
161 self.moveFileUpPushButton = PixmapLabelButton(widget, "up.png",
162 "up.png", name='moveFileUpPushButton')
164 layout37.addWidget(self.moveFileUpPushButton,2,2)
166 self.moveFileDownPushButton = PixmapLabelButton(widget, "down.png",
167 "down.png", name='moveFileDownPushButton')
169 layout37.addWidget(self.moveFileDownPushButton,2,3)
171 self.showTypesPushButton = PixmapLabelButton(widget, "mimetypes.png",
172 None, name='addFilePushButton')
174 layout37.addWidget(self.showTypesPushButton,2,5)
175 self.fileListView = QListView(widget,"fileListView")
176 self.fileListView.addColumn(self.__tr("Order"))
177 self.fileListView.addColumn(self.__tr("Name"))
178 self.fileListView.addColumn(self.__tr("Type"))
179 self.fileListView.addColumn(self.__tr("Path"))
180 self.fileListView.setAllColumnsShowFocus(1)
181 self.fileListView.setShowSortIndicator(1)
182 self.fileListView.setColumnWidth(0, 100)
183 self.fileListView.setColumnWidth(1, 150)
184 self.fileListView.setColumnWidth(2, 75)
185 self.fileListView.setColumnWidth(3, 300)
186 self.fileListView.setItemMargin(2)
187 self.fileListView.setSorting(-1)
189 layout37.addMultiCellWidget(self.fileListView,1,1,0,5)
191 spacer26 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
192 layout37.addItem(spacer26,2,4)
194 self.addFilePushButton.setText(self.__tr("Add File..."))
195 self.showTypesPushButton.setText(self.__tr("Show Types..."))
196 self.removeFilePushButton.setText(self.__tr("Remove File"))
197 self.moveFileDownPushButton.setText(self.__tr("Move Down"))
198 self.moveFileUpPushButton.setText(self.__tr("Move Up"))
200 self.removeFilePushButton.setEnabled(False)
201 self.moveFileDownPushButton.setEnabled(False)
202 self.moveFileUpPushButton.setEnabled(False)
204 self.connect(self.addFilePushButton, SIGNAL("clicked()"), self.addFile_clicked)
205 self.connect(self.removeFilePushButton, SIGNAL("clicked()"), self.removeFile_clicked)
206 self.connect(self.showTypesPushButton, SIGNAL("clicked()"), self.showFileTypes_clicked)
207 self.connect(self.fileListView,SIGNAL("rightButtonClicked(QListViewItem*,const QPoint&, int)"),self.fileListView_rightButtonClicked)
209 self.connect(self.moveFileUpPushButton, SIGNAL("clicked()"), self.moveFileUp_clicked)
210 self.connect(self.moveFileDownPushButton, SIGNAL("clicked()"), self.moveFileDown_clicked)
211 self.connect(self.fileListView, SIGNAL("selectionChanged(QListViewItem*)"),
212 self.fileListView_selectionChanged)
214 self.addWidget(widget, "file_list", maximize=True)
216 def fileListView_selectionChanged(self, i):
218 self.prev_selected_file_index = i.index
219 except AttributeError:
222 flv = self.fileListView
223 selected_item = flv.selectedItem()
224 file_count = flv.childCount()
225 last_item = flv.firstChild()
226 while last_item.nextSibling():
227 last_item = last_item.nextSibling()
229 self.moveFileDownPushButton.setEnabled(file_count > 1 and selected_item is not last_item)
230 self.moveFileUpPushButton.setEnabled(file_count > 1 and selected_item is not flv.firstChild())
232 def fileListView_rightButtonClicked(self, item, pos, col):
233 popup = QPopupMenu(self)
234 popup.insertItem(QIconSet(load_pixmap('list_add', '16x16')),
235 self.__tr("Add File..."), self.addFile_clicked)
238 popup.insertItem(QIconSet(load_pixmap('list_remove', '16x16')),
239 self.__tr("Remove File"), self.removeFile_clicked)
241 if self.fileListView.childCount() > 1:
242 last_item = self.fileListView.firstChild()
243 while last_item is not None and last_item.nextSibling():
244 last_item = last_item.nextSibling()
246 if item is not self.fileListView.firstChild():
247 popup.insertItem(QIconSet(load_pixmap('up', '16x16')),
248 self.__tr("Move Up"), self.moveFileUp_clicked)
250 if item is not last_item:
251 popup.insertItem(QIconSet(load_pixmap('down', '16x16')),
252 self.__tr("Move Down"), self.moveFileDown_clicked)
254 popup.insertSeparator(-1)
255 popup.insertItem(QIconSet(load_pixmap('mimetypes', '16x16')),
256 self.__tr("Show File Types..."), self.showFileTypes_clicked)
260 def moveFileUp_clicked(self):
261 log.debug("Move file up")
263 item = self.fileListView.selectedItem()
264 path, index = item.path, item.index
265 except AttributeError:
269 self.file_list[new_pos], self.file_list[index] = self.file_list[index], self.file_list[new_pos]
271 self.prev_selected_file_index = new_pos
272 self.updateFileList()
274 def moveFileDown_clicked(self):
275 log.debug("Move file down")
277 item = self.fileListView.selectedItem()
278 path, index = item.path, item.index
279 except AttributeError:
283 self.file_list[index], self.file_list[new_pos] = self.file_list[new_pos], self.file_list[index]
285 self.prev_selected_file_index = new_pos
286 self.updateFileList()
288 def addFile(self, path):
289 path = os.path.realpath(path)
290 if os.path.exists(path) and os.access(path, os.R_OK):
291 mime_type = magic.mime_type(path)
292 mime_type_desc = mime_type
296 mime_type_desc = self.MIME_TYPES_DESC[mime_type][0]
298 self.form.FailureUI(self.__tr("<b>You are trying to add a file that cannot be directly printed with this utility.</b><p>To print this file, use the print command in the application that created it."))
300 log.debug("Adding file %s (%s,%s)" % (path, mime_type, mime_type_desc))
301 self.file_list.append((path, mime_type, mime_type_desc))
303 self.form.FailureUI(self.__tr("<b>Unable to add file '%1' to file list (file not found or insufficient permissions).</b><p>Check the file name and try again.").arg(path))
305 self.updateFileList()
307 def updateFileList(self):
308 self.fileListView.clear()
309 temp = self.file_list[:]
315 for path, mime_type, desc in temp:
316 log.debug("path=%s, mime_type=%s, desc=%s, index=%d" % (path, mime_type, desc, index))
317 i = FileListViewItem(self.fileListView, index, os.path.basename(path), desc, path)
319 if self.prev_selected_file_index == index:
320 self.fileListView.setSelected(i, True)
321 self.prev_selected_file_index = index
326 last_item = self.fileListView.firstChild()
327 while last_item is not None and last_item.nextSibling():
328 last_item = last_item.nextSibling()
330 file_count = self.fileListView.childCount()
331 self.moveFileDownPushButton.setEnabled(file_count > 1 and selected_item is not last_item)
332 self.moveFileUpPushButton.setEnabled(file_count > 1 and selected_item is not self.fileListView.firstChild())
333 self.removeFilePushButton.setEnabled(file_count > 0)
334 self.printButton.setEnabled(file_count > 0)
336 def addFile_clicked(self):
337 dlg = QFileDialog(user_conf.workingDirectory(), QString.null, None, None, True)
339 dlg.setCaption("openfile")
340 dlg.setMode(QFileDialog.ExistingFile)
343 if dlg.exec_loop() == QDialog.Accepted:
344 results = dlg.selectedFile()
345 working_directory = unicode(dlg.dir().absPath())
346 log.debug("results: %s" % results)
347 user_conf.setWorkingDirectory(working_directory)
350 self.addFile(unicode(results))
352 def removeFile_clicked(self):
354 path = self.fileListView.selectedItem().path
355 except AttributeError:
358 temp = self.file_list[:]
362 del self.file_list[index]
363 if index == self.prev_selected_file_index:
364 self.prev_selected_file_index = 0
368 self.updateFileList()
370 def showFileTypes_clicked(self):
372 for a in self.allowable_mime_types:
373 x[a] = self.MIME_TYPES_DESC.get(a, ('Unknown', 'n/a'))
376 dlg = AllowableTypesDlg(x, self)
381 widget = self.getWidget()
383 layout12 = QHBoxLayout(widget,5,10,"layout12")
385 self.textLabel5 = QLabel(widget,"textLabel5")
386 layout12.addWidget(self.textLabel5)
387 spacer20 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
388 layout12.addItem(spacer20)
390 self.copiesSpinBox = QSpinBox(widget,"copiesSpinBox")
391 layout12.addWidget(self.copiesSpinBox)
393 self.copiesDefaultPushButton = QPushButton(widget,"copiesDefaultPushButton")
394 layout12.addWidget(self.copiesDefaultPushButton)
396 self.textLabel5.setText(self.__tr("Number of copies:"))
397 self.copiesDefaultPushButton.setText(self.__tr("Default"))
399 self.copiesSpinBox.setMaxValue(99)
400 self.copiesSpinBox.setMinValue(1)
401 self.copiesSpinBox.setValue(1)
403 self.copiesDefaultPushButton.setEnabled(False)
405 self.connect(self.copiesDefaultPushButton, SIGNAL("clicked()"), self.copiesDefaultPushButton_clicked)
406 self.connect(self.copiesSpinBox, SIGNAL("valueChanged(int)"), self.copiesSpinBox_valueChanged)
408 self.addWidget(widget, "copies")
410 def copiesDefaultPushButton_clicked(self):
411 self.copiesSpinBox.setValue(1)
412 self.copiesDefaultPushButton.setEnabled(False)
414 def copiesSpinBox_valueChanged(self, i):
415 self.copiesDefaultPushButton.setEnabled(i != 1)
417 def addPageRange(self):
418 widget = self.getWidget()
420 layout39 = QGridLayout(widget,1,1,5,10,"layout39")
422 self.pageRangeEdit = QLineEdit(widget,"self.pageRangeEdit")
423 self.pageRangeEdit.setEnabled(0)
424 layout39.addWidget(self.pageRangeEdit,0,3)
426 spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
427 layout39.addItem(spacer20_2,0,1)
429 textLabel5_2 = QLabel(widget,"textLabel5_2")
430 layout39.addWidget(textLabel5_2,0,0)
432 self.pagerangeDefaultPushButton = QPushButton(widget,"pagerangeDefaultPushButton")
433 layout39.addWidget(self.pagerangeDefaultPushButton,0,4)
435 self.rangeButtonGroup = QButtonGroup(widget,"self.rangeButtonGroup")
436 self.rangeButtonGroup.setLineWidth(0)
437 self.rangeButtonGroup.setColumnLayout(0,Qt.Vertical)
438 self.rangeButtonGroup.layout().setSpacing(0)
439 self.rangeButtonGroup.layout().setMargin(0)
440 self.rangeButtonGroupLayout = QGridLayout(self.rangeButtonGroup.layout())
441 self.rangeButtonGroupLayout.setAlignment(Qt.AlignTop)
443 radioButton3_2 = QRadioButton(self.rangeButtonGroup,"radioButton3_2")
444 radioButton3_2.setChecked(1)
445 self.rangeButtonGroup.insert( radioButton3_2,0)
446 self.rangeButtonGroupLayout.addWidget(radioButton3_2,0,0)
448 radioButton4_2 = QRadioButton(self.rangeButtonGroup,"radioButton4_2")
449 self.rangeButtonGroup.insert( radioButton4_2,1)
450 self.rangeButtonGroupLayout.addWidget(radioButton4_2,0,1)
452 layout39.addWidget(self.rangeButtonGroup,0,2)
454 self.bg = self.pageRangeEdit.paletteBackgroundColor()
455 self.invalid_page_range = False
457 self.pageRangeEdit.setValidator(RangeValidator(self.pageRangeEdit))
459 textLabel5_2.setText(self.__tr("Page Range:"))
460 radioButton3_2.setText(self.__tr("All pages"))
461 radioButton4_2.setText(self.__tr("Page range:"))
463 self.pagerangeDefaultPushButton.setText(self.__tr("Default"))
465 self.pagerangeDefaultPushButton.setEnabled(False)
467 self.connect(self.rangeButtonGroup, SIGNAL("clicked(int)"), self.rangeButtonGroup_clicked)
468 self.connect(self.pageRangeEdit,SIGNAL("lostFocus()"),self.pageRangeEdit_lostFocus)
469 self.connect(self.pageRangeEdit,SIGNAL("textChanged(const QString&)"),self.pageRangeEdit_textChanged)
470 self.connect(self.pagerangeDefaultPushButton, SIGNAL("clicked()"), self.pagerangeDefaultPushButton_clicked)
472 self.addWidget(widget, "range")
474 def pagerangeDefaultPushButton_clicked(self):
475 self.rangeButtonGroup.setButton(0)
476 self.pagerangeDefaultPushButton.setEnabled(False)
477 self.pageRangeEdit.setEnabled(False)
479 def rangeButtonGroup_clicked(self, a0):
480 self.pages_button_group = a0
481 self.pageRangeEdit.setEnabled(a0 == 1)
482 self.pagerangeDefaultPushButton.setEnabled(a0 == 1)
484 def pageRangeEdit_lostFocus(self):
487 x = utils.expand_range(unicode(self.pageRangeEdit.text()))
489 log.error("Invalid page range entered.")
490 self.invalid_page_range = True
491 self.pageRangeEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))
494 self.pageRangeEdit.setText(QString(utils.collapse_range(x)))
495 self.pageRangeEdit.setPaletteBackgroundColor(self.bg)
496 self.invalid_page_range = False
498 def pageRangeEdit_textChanged(self,a0):
501 x = utils.expand_range(str(self.pageRangeEdit.text()))
503 self.invalid_page_range = True
504 self.pageRangeEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))
507 self.pageRangeEdit.setPaletteBackgroundColor(self.bg)
508 self.invalid_page_range = False
510 def addPageSet(self):
511 widget = self.getWidget()
513 layout34 = QHBoxLayout(widget,5,10,"layout34")
515 self.textLabel5_4 = QLabel(widget,"textLabel5_4")
516 layout34.addWidget(self.textLabel5_4)
517 spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
518 layout34.addItem(spacer20_4)
520 self.pageSetComboBox = QComboBox(0,widget,"pageSetComboBox")
521 layout34.addWidget(self.pageSetComboBox)
523 self.pagesetDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
524 layout34.addWidget(self.pagesetDefaultPushButton)
526 self.textLabel5_4.setText(self.__tr("Page set:"))
527 self.pageSetComboBox.clear()
528 self.pageSetComboBox.insertItem(self.__tr("All pages"))
529 self.pageSetComboBox.insertItem(self.__tr("Even pages"))
530 self.pageSetComboBox.insertItem(self.__tr("Odd pages"))
531 self.pagesetDefaultPushButton.setText(self.__tr("Default"))
533 self.pagesetDefaultPushButton.setEnabled(False)
535 self.connect(self.pageSetComboBox, SIGNAL("activated(int)"), self.pageSetComboBox_activated)
536 self.connect(self.pagesetDefaultPushButton, SIGNAL("clicked()"), self.pagesetDefaultPushButton_clicked)
538 self.addWidget(widget, "set")
540 def pagesetDefaultPushButton_clicked(self):
541 self.pagesetDefaultPushButton.setEnabled(False)
542 self.pageSetComboBox.setCurrentItem(0)
544 def pageSetComboBox_activated(self, i):
545 self.pagesetDefaultPushButton.setEnabled(i != 0)
551 ## def addJobStorage(self):
552 ## self.addJobStorageMode()
553 ## self.addJobStoragePIN()
554 ## self.addJobStorageUsername()
555 ## self.addJobStorageID()
556 ## self.addJobStorageIDExists()
557 ## self.jobStorageDisable()
560 ## def addJobStorageMode(self):
561 ## widget = self.getWidget()
563 ## layout34 = QHBoxLayout(widget,5,10,"layout34")
565 ## self.jobStorageModeLabel = QLabel(widget,"jobStorageModeLabel")
566 ## layout34.addWidget(self.jobStorageModeLabel)
567 ## spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
568 ## layout34.addItem(spacer20_4)
570 ## self.jobStorageModeComboBox = QComboBox(0,widget,"jobStorageModeComboBox")
571 ## layout34.addWidget(self.jobStorageModeComboBox)
573 ## self.jobStorageModeDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
574 ## layout34.addWidget(self.jobStorageModeDefaultPushButton)
576 ## self.jobStorageModeLabel.setText(self.__tr("Job Storage Mode:"))
577 ## self.jobStorageModeComboBox.clear()
578 ## self.jobStorageModeComboBox.insertItem(self.__tr("Off"))
579 ## self.jobStorageModeComboBox.insertItem(self.__tr("Proof and Hold"))
580 ## self.jobStorageModeComboBox.insertItem(self.__tr("Personal/Private Job"))
581 ## self.jobStorageModeComboBox.insertItem(self.__tr("Quick Copy"))
582 ## self.jobStorageModeComboBox.insertItem(self.__tr("Stored Job"))
584 ## self.jobStorageModeDefaultPushButton.setText(self.__tr("Default"))
585 ## self.jobStorageModeDefaultPushButton.setEnabled(False)
587 ## self.connect(self.jobStorageModeComboBox, SIGNAL("activated(int)"), self.jobStorageModeComboBox_activated)
588 ## self.connect(self.jobStorageModeDefaultPushButton, SIGNAL("clicked()"), self.jobStorageModeDefaultPushButton_clicked)
590 ## self.addWidget(widget, "job_storage_mode")
592 ## def jobStorageModeComboBox_activated(self, a):
593 ## self.job_storage_mode = a
596 ## self.jobStorageDisable()
598 ## elif a == 1: # Proof and Hold
599 ## self.jobStorageModeDefaultPushButton.setEnabled(True)
600 ## self.jobStorageUserJobEnable(True)
601 ## self.jobStoragePINEnable(False)
603 ## elif a == 2: # Private Job
604 ## self.jobStorageModeDefaultPushButton.setEnabled(True)
605 ## self.jobStoragePINEnable(True)
606 ## self.jobStorageUserJobEnable(True)
608 ## elif a == 3: # Quick Copy
609 ## self.jobStorageModeDefaultPushButton.setEnabled(True)
610 ## self.jobStoragePINEnable(False)
611 ## self.jobStorageUserJobEnable(True)
613 ## elif a == 4: # Stored Job
614 ## self.jobStorageModeDefaultPushButton.setEnabled(True)
615 ## self.jobStoragePINEnable(True) # ???
616 ## self.jobStorageUserJobEnable(True)
618 ## def jobStorageModeDefaultPushButton_clicked(self):
619 ## self.jobStorageModeComboBox.setCurrentItem(0)
620 ## self.job_storage_mode = 0
622 ## def jobStorageDisable(self): # Turn all Off
623 ## self.jobStorageModeDefaultPushButton.setEnabled(False)
624 ## self.jobStoragePINEnable(False)
625 ## self.jobStorageUserJobEnable(False)
627 ## def jobStoragePINEnable(self, e=True): # PIN On/Off
628 ## t = e and self.jobStoragePINButtonGroup.selectedId() == 1
629 ## self.jobStoragePINButtonGroup.setEnabled(e)
630 ## self.jobStoragePINEdit.setEnabled(t)
631 ## self.jobStoragePINDefaultPushButton.setEnabled(t)
633 ## def jobStorageUserJobEnable(self, e=True): # Username/Job ID/Job ID Exists On/Off
634 ## t = e and self.jobStorageUsernameButtonGroup.selectedId() == 1
635 ## self.jobStorageUsernameButtonGroup.setEnabled(e)
636 ## self.jobStorageUsernameDefaultPushButton.setEnabled(t)
637 ## self.jobStorageUsernameEdit.setEnabled(t)
639 ## t = e and self.jobStorageIDButtonGroup.selectedId() == 1
640 ## self.jobStorageIDButtonGroup.setEnabled(e)
641 ## self.jobStorageIDDefaultPushButton.setEnabled(t)
642 ## self.jobStorageIDEdit.setEnabled(t)
644 ## t = e and self.jobStorageIDExistsComboBox.currentItem() == 1
645 ## self.jobStorageIDExistsComboBox.setEnabled(e)
646 ## self.jobStorageIDExistsDefaultPushButton.setEnabled(t)
653 ## def addJobStoragePIN(self):
654 ## widget = self.getWidget()
656 ## layout39 = QGridLayout(widget,1,1,5,10,"layout39")
658 ## self.jobStoragePINEdit = QLineEdit(widget,"self.jobStoragePINEdit")
659 ## self.jobStoragePINEdit.setMaxLength(4)
660 ## self.jobStoragePINEdit.setText(self.job_storage_pin)
661 ## layout39.addWidget(self.jobStoragePINEdit,0,3)
663 ## spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
664 ## layout39.addItem(spacer20_2,0,1)
666 ## textLabel5_2 = QLabel(widget,"textLabel5_2")
667 ## layout39.addWidget(textLabel5_2,0,0)
669 ## self.jobStoragePINDefaultPushButton = QPushButton(widget,"jobStoragePINDefaultPushButton")
670 ## layout39.addWidget(self.jobStoragePINDefaultPushButton,0,4)
672 ## self.jobStoragePINButtonGroup = QButtonGroup(widget,"self.jobStoragePINButtonGroup")
673 ## self.jobStoragePINButtonGroup.setLineWidth(0)
674 ## self.jobStoragePINButtonGroup.setColumnLayout(0,Qt.Vertical)
675 ## self.jobStoragePINButtonGroup.layout().setSpacing(0)
676 ## self.jobStoragePINButtonGroup.layout().setMargin(0)
677 ## self.jobStoragePINButtonGroupLayout = QGridLayout(self.jobStoragePINButtonGroup.layout())
678 ## self.jobStoragePINButtonGroupLayout.setAlignment(Qt.AlignTop)
680 ## radioButton3_2 = QRadioButton(self.jobStoragePINButtonGroup,"radioButton3_2")
681 ## radioButton3_2.setChecked(1)
682 ## self.jobStoragePINButtonGroup.insert( radioButton3_2,0)
683 ## self.jobStoragePINButtonGroupLayout.addWidget(radioButton3_2,0,0)
685 ## radioButton4_2 = QRadioButton(self.jobStoragePINButtonGroup,"radioButton4_2")
686 ## self.jobStoragePINButtonGroup.insert( radioButton4_2,1)
687 ## self.jobStoragePINButtonGroupLayout.addWidget(radioButton4_2,0,1)
689 ## layout39.addWidget(self.jobStoragePINButtonGroup,0,2)
691 ## self.bg = self.jobStoragePINEdit.paletteBackgroundColor()
692 ## self.invalid_page_range = False
694 ## self.jobStoragePINEdit.setValidator(PINValidator(self.jobStoragePINEdit))
696 ## textLabel5_2.setText(self.__tr("Make Job Private (use PIN to print):"))
697 ## radioButton3_2.setText(self.__tr("Public/Off"))
698 ## radioButton4_2.setText(self.__tr("Private/Use PIN to Print:"))
700 ## self.jobStoragePINDefaultPushButton.setText(self.__tr("Default"))
702 ## self.connect(self.jobStoragePINButtonGroup, SIGNAL("clicked(int)"), self.jobStoragePINButtonGroup_clicked)
703 ## self.connect(self.jobStoragePINEdit,SIGNAL("lostFocus()"),self.jobStoragePINEdit_lostFocus)
704 ## self.connect(self.jobStoragePINEdit,SIGNAL("textChanged(const QString&)"),self.jobStoragePINEdit_textChanged)
705 ## self.connect(self.jobStoragePINDefaultPushButton, SIGNAL("clicked()"), self.jobStoragePINDefaultPushButton_clicked)
707 ## self.addWidget(widget, "job_storage_pin")
709 ## def jobStoragePINButtonGroup_clicked(self, a):
710 ## if a == 0: # Public/Off
711 ## self.jobStoragePINDefaultPushButton.setEnabled(False)
712 ## self.jobStoragePINEdit.setEnabled(False)
713 ## self.job_storage_use_pin = False
714 ## self.job_storage_pin = u"0000"
716 ## else: # On/Private/Use PIN
717 ## self.jobStoragePINDefaultPushButton.setEnabled(True)
718 ## self.jobStoragePINEdit.setEnabled(True)
719 ## self.job_storage_use_pin = True
720 ## self.job_storage_pin = unicode(self.jobStoragePINEdit.text())
722 ## def jobStoragePINEdit_lostFocus(self):
725 ## def jobStoragePINEdit_textChanged(self, a):
726 ## self.job_storage_pin = unicode(a)
728 ## def jobStoragePINDefaultPushButton_clicked(self):
729 ## self.jobStoragePINButtonGroup.setButton(0)
730 ## self.jobStoragePINDefaultPushButton.setEnabled(False)
731 ## self.jobStoragePINEdit.setEnabled(False)
732 ## self.job_storage_use_pin = False
736 ## def addJobStorageUsername(self):
737 ## widget = self.getWidget()
739 ## layout39 = QGridLayout(widget,1,1,5,10,"layout39")
741 ## self.jobStorageUsernameEdit = QLineEdit(widget,"self.jobStorageUsernameEdit")
742 ## self.jobStorageUsernameEdit.setMaxLength(16)
743 ## self.jobStorageUsernameEdit.setText(self.job_storage_username)
744 ## layout39.addWidget(self.jobStorageUsernameEdit,0,3)
746 ## spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
747 ## layout39.addItem(spacer20_2,0,1)
749 ## textLabel5_2 = QLabel(widget,"textLabel5_2")
750 ## layout39.addWidget(textLabel5_2,0,0)
752 ## self.jobStorageUsernameDefaultPushButton = QPushButton(widget,"jobStorageUsernameDefaultPushButton")
753 ## layout39.addWidget(self.jobStorageUsernameDefaultPushButton,0,4)
755 ## self.jobStorageUsernameButtonGroup = QButtonGroup(widget,"self.jobStorageUsernameButtonGroup")
756 ## self.jobStorageUsernameButtonGroup.setLineWidth(0)
757 ## self.jobStorageUsernameButtonGroup.setColumnLayout(0,Qt.Vertical)
758 ## self.jobStorageUsernameButtonGroup.layout().setSpacing(0)
759 ## self.jobStorageUsernameButtonGroup.layout().setMargin(0)
760 ## self.jobStorageUsernameButtonGroupLayout = QGridLayout(self.jobStorageUsernameButtonGroup.layout())
761 ## self.jobStorageUsernameButtonGroupLayout.setAlignment(Qt.AlignTop)
763 ## radioButton3_2 = QRadioButton(self.jobStorageUsernameButtonGroup,"radioButton3_2")
764 ## radioButton3_2.setChecked(1)
765 ## self.jobStorageUsernameButtonGroup.insert( radioButton3_2,0)
766 ## self.jobStorageUsernameButtonGroupLayout.addWidget(radioButton3_2,0,0)
768 ## radioButton4_2 = QRadioButton(self.jobStorageUsernameButtonGroup,"radioButton4_2")
769 ## self.jobStorageUsernameButtonGroup.insert( radioButton4_2,1)
770 ## self.jobStorageUsernameButtonGroupLayout.addWidget(radioButton4_2,0,1)
772 ## layout39.addWidget(self.jobStorageUsernameButtonGroup,0,2)
774 ## self.bg = self.jobStorageUsernameEdit.paletteBackgroundColor()
775 ## self.invalid_page_range = False
777 ## self.jobStorageUsernameEdit.setValidator(TextValidator(self.jobStorageUsernameEdit))
779 ## textLabel5_2.setText(self.__tr("User name (for job identification):"))
780 ## radioButton3_2.setText(self.__tr("Automatic"))
781 ## radioButton4_2.setText(self.__tr("Custom:"))
783 ## self.jobStorageUsernameDefaultPushButton.setText(self.__tr("Default"))
785 ## self.connect(self.jobStorageUsernameButtonGroup, SIGNAL("clicked(int)"), self.jobStorageUsernameButtonGroup_clicked)
786 ## self.connect(self.jobStorageUsernameEdit,SIGNAL("lostFocus()"),self.jobStorageUsernameEdit_lostFocus)
787 ## self.connect(self.jobStorageUsernameEdit,SIGNAL("textChanged(const QString&)"),self.jobStorageUsernameEdit_textChanged)
788 ## self.connect(self.jobStorageUsernameDefaultPushButton, SIGNAL("clicked()"), self.jobStorageUsernameDefaultPushButton_clicked)
790 ## self.addWidget(widget, "job_storage_username")
792 ## def jobStorageUsernameButtonGroup_clicked(self, a):
793 ## if a == 0: # Automatic
794 ## self.jobStorageUsernameDefaultPushButton.setEnabled(False)
795 ## self.jobStorageUsernameEdit.setEnabled(False)
796 ## self.job_storage_auto_username = True
797 ## self.job_storage_username = unicode(prop.username[:16])
800 ## self.jobStorageUsernameDefaultPushButton.setEnabled(True)
801 ## self.jobStorageUsernameEdit.setEnabled(True)
802 ## self.job_storage_auto_username = False
803 ## self.job_storage_username = unicode(self.jobStorageUsernameEdit.text())
805 ## def jobStorageUsernameEdit_lostFocus(saddJobStorageIDelf):
808 ## def jobStorageUsernameEdit_textChanged(self, a):
809 ## self.job_storage_username = unicode(a)
811 ## def jobStorageUsernameDefaultPushButton_clicked(self):
812 ## self.jobStorageUsernameButtonGroup.setButton(0)
813 ## self.jobStorageUsernameDefaultPushButton.setEnabled(False)
814 ## self.jobStorageUsernameEdit.setEnabled(False)
815 ## self.job_storage_auto_username = True
816 ## self.job_storage_username = unicode(prop.username[:16])
820 ## def addJobStorageID(self):
821 ## widget = self.getWidget()
823 ## layout39 = QGridLayout(widget,1,1,5,10,"layout39")
825 ## self.jobStorageIDEdit = QLineEdit(widget,"self.jobStorageIDEdit")
826 ## self.jobStorageIDEdit.setMaxLength(16)
827 ## self.jobStorageIDEdit.setText(self.job_storage_jobname)
828 ## layout39.addWidget(self.jobStorageIDEdit,0,3)
830 ## spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
831 ## layout39.addItem(spacer20_2,0,1)
833 ## textLabel5_2 = QLabel(widget,"textLabel5_2")
834 ## layout39.addWidget(textLabel5_2,0,0)
836 ## self.jobStorageIDDefaultPushButton = QPushButton(widget,"jobStorageIDDefaultPushButton")
837 ## layout39.addWidget(self.jobStorageIDDefaultPushButton,0,4)
839 ## self.jobStorageIDButtonGroup = QButtonGroup(widget,"self.jobStorageIDButtonGroup")
840 ## self.jobStorageIDButtonGroup.setLineWidth(0)
841 ## self.jobStorageIDButtonGroup.setColumnLayout(0,Qt.Vertical)
842 ## self.jobStorageIDButtonGroup.layout().setSpacing(0)
843 ## self.jobStorageIDButtonGroup.layout().setMargin(0)
844 ## self.jobStorageIDButtonGroupLayout = QGridLayout(self.jobStorageIDButtonGroup.layout())
845 ## self.jobStorageIDButtonGroupLayout.setAlignment(Qt.AlignTop)
847 ## radioButton3_2 = QRadioButton(self.jobStorageIDButtonGroup,"radioButton3_2")
848 ## radioButton3_2.setChecked(1)
849 ## self.jobStorageIDButtonGroup.insert( radioButton3_2,0)
850 ## self.jobStorageIDButtonGroupLayout.addWidget(radioButton3_2,0,0)
852 ## radioButton4_2 = QRadioButton(self.jobStorageIDButtonGroup,"radioButton4_2")
853 ## self.jobStorageIDButtonGroup.insert( radioButton4_2,1)
854 ## self.jobStorageIDButtonGroupLayout.addWidget(radioButton4_2,0,1)
856 ## layout39.addWidget(self.jobStorageIDButtonGroup,0,2)
858 ## self.bg = self.jobStorageIDEdit.paletteBackgroundColor()
859 ## self.invalid_page_range = False
861 ## self.jobStorageIDEdit.setValidator(TextValidator(self.jobStorageIDEdit))
863 ## textLabel5_2.setText(self.__tr("Job name (for job identification):"))
864 ## radioButton3_2.setText(self.__tr("Automatic"))
865 ## radioButton4_2.setText(self.__tr("Custom:"))
867 ## self.jobStorageIDDefaultPushButton.setText(self.__tr("Default"))
869 ## self.connect(self.jobStorageIDButtonGroup, SIGNAL("clicked(int)"), self.jobStorageIDButtonGroup_clicked)
870 ## self.connect(self.jobStorageIDEdit,SIGNAL("lostFocus()"),self.jobStorageIDEdit_lostFocus)
871 ## self.connect(self.jobStorageIDEdit,SIGNAL("textChanged(const QString&)"),self.jobStorageIDEdit_textChanged)
872 ## self.connect(self.jobStorageIDDefaultPushButton, SIGNAL("clicked()"), self.jobStorageIDDefaultPushButton_clicked)
874 ## self.addWidget(widget, "job_storage_ID")
876 ## def jobStorageIDButtonGroup_clicked(self, a):
877 ## if a == 0: # Automatic
878 ## self.jobStorageIDDefaultPushButton.setEnabled(False)
879 ## self.jobStorageIDEdit.setEnabled(False)
880 ## self.job_storage_auto_jobname = True
881 ## self.job_storage_jobname = unicode(time.strftime("%a, %d %b %Y %H:%M:%S"))
884 ## self.jobStorageIDDefaultPushButton.setEnabled(True)
885 ## self.jobStorageIDEdit.setEnabled(True)
886 ## self.job_storage_auto_jobname = False
887 ## self.job_storage_jobname = unicode(self.jobStorageIDEdit.text())
889 ## def jobStorageIDEdit_lostFocus(self):
892 ## def jobStorageIDEdit_textChanged(self, a):
893 ## self.job_storage_jobname = unicode(a)
895 ## def jobStorageIDDefaultPushButton_clicked(self):
896 ## self.jobStorageIDButtonGroup.setButton(0)
897 ## self.jobStorageIDDefaultPushButton.setEnabled(False)
898 ## self.jobStorageIDEdit.setEnabled(False)
899 ## self.job_storage_auto_jobname = True
900 ## self.job_storage_jobname = unicode(time.strftime("%a, %d %b %Y %H:%M:%S"))
904 ## def addJobStorageIDExists(self):
905 ## widget = self.getWidget()
907 ## layout34 = QHBoxLayout(widget,5,10,"layout34")
909 ## self.jobStorageIDExistsLabel = QLabel(widget,"jobStorageIDExistsLabel")
910 ## layout34.addWidget(self.jobStorageIDExistsLabel)
911 ## spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
912 ## layout34.addItem(spacer20_4)
914 ## self.jobStorageIDExistsComboBox = QComboBox(0,widget,"jobStorageIDExistsComboBox")
915 ## layout34.addWidget(self.jobStorageIDExistsComboBox)
917 ## self.jobStorageIDExistsDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
918 ## layout34.addWidget(self.jobStorageIDExistsDefaultPushButton)
920 ## self.jobStorageIDExistsLabel.setText(self.__tr("If Job Name already exists:"))
921 ## self.jobStorageIDExistsComboBox.clear()
922 ## self.jobStorageIDExistsComboBox.insertItem(self.__tr("Replace existing job"))
923 ## self.jobStorageIDExistsComboBox.insertItem(self.__tr("Use Job Name + (1-99)"))
925 ## self.jobStorageIDExistsDefaultPushButton.setText(self.__tr("Default"))
927 ## self.connect(self.jobStorageIDExistsComboBox, SIGNAL("activated(int)"), self.jobStorageIDExistsComboBox_activated)
928 ## self.connect(self.jobStorageIDExistsDefaultPushButton, SIGNAL("clicked()"), self.jobStorageIDExistsDefaultPushButton_clicked)
930 ## self.addWidget(widget, "job_storage_id_exists")
932 ## def jobStorageIDExistsComboBox_activated(self, a):
933 ## self.jobStorageIDExistsDefaultPushButton.setEnabled(a==1)
934 ## self.job_storage_job_exist = a
936 ## def jobStorageIDExistsDefaultPushButton_clicked(self):
937 ## self.jobStorageIDExistsComboBox.setCurrentItem(0)
938 ## self.jobStorageIDExistsDefaultPushButton.setEnabled(False)
939 ## self.job_storage_job_exist = 0
946 def printButton_clicked(self):
947 if self.invalid_page_range:
948 self.form.FailureUI(self.__tr("<b>Cannot print: Invalid page range: %1</b><p>A valid page range is a list of pages or ranges of pages separated by commas (e.g., 1-2,4,6-7)").arg(self.pageRangeEdit.text()))
953 self.cur_device.open()
955 self.form.FailureUI(self.__tr("<b>Cannot print: Device is busy or not available.</b><p>Please check device and try again."))
958 if 1: # Go ahead and allow - print will be queued in CUPS if not rejecting
959 printers = cups.getPrinters()
961 if p.name == self.cur_printer:
964 if p.state == cups.IPP_PRINTER_STATE_STOPPED:
965 self.form.FailureUI(self.__tr("<b>Cannot print: Printer is stopped.</b><p>Please START the printer to continue this print. Job will begin printing once printer is started."))
968 self.form.FailureUI(self.__tr("<b>Cannot print: Printer is not accepting jobs.</b><p>Please set the printer to ACCEPTING JOBS to continue printing."))
971 copies = int(self.copiesSpinBox.value())
972 all_pages = self.pages_button_group == 0
973 page_range = unicode(self.pageRangeEdit.text())
974 page_set = int(self.pageSetComboBox.currentItem())
977 cups.openPPD(self.cur_printer)
978 current_options = dict(cups.getOptions())
981 nup = int(current_options.get("number-up", 1))
982 log.debug("number-up = %d" % nup)
984 for p, t, d in self.file_list:
986 alt_nup = (nup > 1 and t == 'application/postscript' and utils.which('psnup'))
988 if utils.which('lpr'):
990 cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lpr -P', self.cur_printer])
992 cmd = ' '.join(['lpr -P', self.cur_printer])
995 cmd = ' '.join([cmd, '-#%d' % copies])
999 cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lp -c -d', self.cur_printer])
1001 cmd = ' '.join(['lp -c -d', self.cur_printer])
1004 cmd = ' '.join([cmd, '-n%d' % copies])
1007 if not all_pages and len(page_range) > 0:
1008 cmd = ' '.join([cmd, '-o page-ranges=%s' % page_range])
1012 cmd = ' '.join([cmd, '-o page-set=even'])
1014 cmd = ' '.join([cmd, '-o page-set=odd'])
1018 # self.job_storage_mode = (0=Off, 1=P&H, 2=PJ, 3=QC, 4=SJ)
1019 # self.job_storage_pin = u"" (dddd)
1020 # self.job_storage_use_pin = True|False
1021 # self.job_storage_username = u""
1022 # self.job_storage_auto_username = True|False
1023 # self.job_storage_jobname = u""
1024 # self.job_storage_auto_jobname = True|False
1025 # self.job_storage_job_exist = (0=replace, 1=job name+(1-99))
1027 if self.job_storage_avail:
1028 if self.job_storage_mode: # On
1030 if self.job_storage_mode == 1: # Proof and Hold
1031 cmd = ' '.join([cmd, '-o HOLD=PROOF'])
1033 elif self.job_storage_mode == 2: # Private Job
1034 if self.job_storage_use_pin:
1035 cmd = ' '.join([cmd, '-o HOLD=ON'])
1036 cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
1037 cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
1039 cmd = ' '.join([cmd, '-o HOLD=PROOF'])
1040 cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
1042 elif self.job_storage_mode == 3: # Quick Copy
1043 cmd = ' '.join([cmd, '-o HOLD=ON'])
1044 cmd = ' '.join([cmd, '-o HOLDTYPE=PUBLIC'])
1046 elif self.job_storage_mode == 4: # Store Job
1047 if self.job_storage_use_pin:
1048 cmd = ' '.join([cmd, '-o HOLD=STORE'])
1049 cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
1050 cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
1052 cmd = ' '.join([cmd, '-o HOLD=STORE'])
1054 cmd = ' '.join([cmd, '-o USERNAME=%s' % self.job_storage_username.encode('ascii')\
1055 .replace(" ", "_")])
1057 cmd = ' '.join([cmd, '-o JOBNAME=%s' % self.job_storage_jobname.encode('ascii')\
1058 .replace(" ", "_")])
1060 if self.job_storage_job_exist == 1:
1061 cmd = ' '.join([cmd, '-o DUPLICATEJOB=APPEND'])
1063 cmd = ' '.join([cmd, '-o DUPLICATEJOB=REPLACE'])
1066 cmd = ' '.join([cmd, '-o HOLD=OFF'])
1070 cmd = ''.join([cmd, ' "', p, '"'])
1072 log.debug("Printing: %s" % cmd)
1074 code = os.system(cmd)
1076 log.error("Print command failed.")
1077 self.form.FailureUI(self.__tr("Print command failed with error code %1").arg(code))
1082 self.cur_device.close()
1084 def funcButton_clicked(self):
1087 def __tr(self,s,c = None):
1088 return qApp.translate("ScrollPrintView",s,c)