def render_file(self, path, title, mime_type, force_single_page=False): all_pages = True page_range = '' page_set = 0 nup = 1 cups.resetOptions() if mime_type in ["application/x-cshell", "application/x-perl", "application/x-python", "application/x-shell", "application/x-sh", "text/plain",]: cups.addOption('prettyprint') if nup > 1: cups.addOption('number-up=%d' % nup) if force_single_page: cups.addOption('page-ranges=1') # Force coverpage to 1 page sent_job_id = cups.printFile(self.current_printer, path, title) cups.resetOptions() log.debug("Job ID=%d" % sent_job_id) job_id = 0 time.sleep(1) fax_file = '' complete = False end_time = time.time() + 300.0 # wait for 5 min. max while time.time() < end_time: log.debug("Waiting for fax... type =%s"%type(self.dev.device_uri)) result = list(self.service.CheckForWaitingFax(self.dev.device_uri, prop.username, sent_job_id)) fax_file = str(result[7]) log.debug("Fax file=%s" % fax_file) if fax_file: break if self.check_for_cancel(): log.error("Render canceled. Canceling job #%d..." % sent_job_id) cups.cancelJob(sent_job_id) return '', True time.sleep(1) else: log.error("Timeout waiting for rendering. Canceling job #%d..." % sent_job_id) cups.cancelJob(sent_job_id) return '', False return fax_file, False
def render_file(self, path, title, mime_type, force_single_page=False): all_pages = True page_range = '' page_set = 0 nup = 1 cups.resetOptions() if mime_type in ["application/x-cshell", "application/x-perl", "application/x-python", "application/x-shell", "application/x-sh", "text/plain",]: cups.addOption('prettyprint') if nup > 1: cups.addOption('number-up=%d' % nup) if force_single_page: cups.addOption('page-ranges=1') # Force coverpage to 1 page sent_job_id = cups.printFile(self.current_printer, path, title) cups.resetOptions() log.debug("Job ID=%d" % sent_job_id) job_id = 0 time.sleep(1) fax_file = '' complete = False end_time = time.time() + 300.0 # wait for 5 min. max while time.time() < end_time: log.debug("Waiting for fax...") result = list(self.service.CheckForWaitingFax(self.dev.device_uri, prop.username, sent_job_id)) fax_file = str(result[7]) log.debug("Fax file=%s" % fax_file) if fax_file: break if self.check_for_cancel(): log.error("Render canceled. Canceling job #%d..." % sent_job_id) cups.cancelJob(sent_job_id) return '', True time.sleep(1) else: log.error("Timeout waiting for rendering. Canceling job #%d..." % sent_job_id) cups.cancelJob(sent_job_id) return '', False return fax_file, False
def printButton_clicked(self): if self.invalid_page_range: 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())) return try: try: self.cur_device.open() except Error: self.form.FailureUI(self.__tr("<b>Cannot print: Device is busy or not available.</b><p>Please check device and try again.")) return if 1: # Go ahead and allow - print will be queued in CUPS if not rejecting printers = cups.getPrinters() for p in printers: if p.name == self.cur_printer: break if p.state == cups.IPP_PRINTER_STATE_STOPPED: 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.")) if not p.accepting: 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.")) return copies = int(self.copiesSpinBox.value()) all_pages = self.pages_button_group == 0 page_range = unicode(self.pageRangeEdit.text()) page_set = int(self.pageSetComboBox.currentItem()) cups.resetOptions() cups.openPPD(self.cur_printer) current_options = dict(cups.getOptions()) cups.closePPD() nup = int(current_options.get("number-up", 1)) log.debug("number-up = %d" % nup) for p, t, d in self.file_list: alt_nup = (nup > 1 and t == 'application/postscript' and utils.which('psnup')) if utils.which('lpr'): if alt_nup: cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lpr -P', self.cur_printer]) else: cmd = ' '.join(['lpr -P', self.cur_printer]) if copies > 1: cmd = ' '.join([cmd, '-#%d' % copies]) else: if alt_nup: cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lp -c -d', self.cur_printer]) else: cmd = ' '.join(['lp -c -d', self.cur_printer]) if copies > 1: cmd = ' '.join([cmd, '-n%d' % copies]) if not all_pages and len(page_range) > 0: cmd = ' '.join([cmd, '-o page-ranges=%s' % page_range]) if page_set > 0: if page_set == 1: cmd = ' '.join([cmd, '-o page-set=even']) else: cmd = ' '.join([cmd, '-o page-set=odd']) # Job Storage # self.job_storage_mode = (0=Off, 1=P&H, 2=PJ, 3=QC, 4=SJ) # self.job_storage_pin = u"" (dddd) # self.job_storage_use_pin = True|False # self.job_storage_username = u"" # self.job_storage_auto_username = True|False # self.job_storage_jobname = u"" # self.job_storage_auto_jobname = True|False # self.job_storage_job_exist = (0=replace, 1=job name+(1-99)) if self.job_storage_avail: if self.job_storage_mode: # On if self.job_storage_mode == 1: # Proof and Hold cmd = ' '.join([cmd, '-o HOLD=PROOF']) elif self.job_storage_mode == 2: # Private Job if self.job_storage_use_pin: cmd = ' '.join([cmd, '-o HOLD=ON']) cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE']) cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')]) else: cmd = ' '.join([cmd, '-o HOLD=PROOF']) cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE']) elif self.job_storage_mode == 3: # Quick Copy cmd = ' '.join([cmd, '-o HOLD=ON']) cmd = ' '.join([cmd, '-o HOLDTYPE=PUBLIC']) elif self.job_storage_mode == 4: # Store Job if self.job_storage_use_pin: cmd = ' '.join([cmd, '-o HOLD=STORE']) cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE']) cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')]) else: cmd = ' '.join([cmd, '-o HOLD=STORE']) cmd = ' '.join([cmd, '-o USERNAME=%s' % self.job_storage_username.encode('ascii')\ .replace(" ", "_")]) cmd = ' '.join([cmd, '-o JOBNAME=%s' % self.job_storage_jobname.encode('ascii')\ .replace(" ", "_")]) if self.job_storage_job_exist == 1: cmd = ' '.join([cmd, '-o DUPLICATEJOB=APPEND']) else: cmd = ' '.join([cmd, '-o DUPLICATEJOB=REPLACE']) else: # Off cmd = ' '.join([cmd, '-o HOLD=OFF']) if not alt_nup: cmd = ''.join([cmd, ' "', p, '"']) log.debug("Printing: %s" % cmd) code = os.system(cmd) if code != 0: log.error("Print command failed.") self.form.FailureUI(self.__tr("Print command failed with error code %1").arg(code)) self.form.close() finally: self.cur_device.close()
mg, version, pages, hort_dpi, vert_dpi, page_size, \ resolution, encoding, reserved1, reserved2 = struct.unpack(">8sBIHHBBBII", header) if mg != b'hplip_g3': log.error("%s: Invalid file header. Bad magic." % f) sys.exit(1) file_list.append((f, mime_type, "", "", pages)) else: all_pages = True page_range = '' page_set = 0 nup = 1 cups.resetOptions() if mime_type in ["application/x-cshell", "application/x-perl", "application/x-python", "application/x-shell", "text/plain",] and prettyprint: cups.addOption('prettyprint') if nup > 1: cups.addOption('number-up=%d' % nup) while True: cups_printers = cups.getPrinters()
def updateInfoTable(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.DynamicTableWidget.clear() self.DynamicTableWidget.setRowCount(0) self.DynamicTableWidget.setColumnCount(0) flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled while self.TabWidget.count() > 3: self.TabWidget.removeTab(3) self.DynamicTableWidget.clear() self.DynamicTableWidget.setRowCount(0) self.DynamicTableWidget.setColumnCount(len(self.headers)) self.DynamicTableWidget.setHorizontalHeaderLabels(self.headers) # # Static Data # try: d = device.Device(self.device_uri, None) except Error: QApplication.restoreOverrideCursor() FailureUI(self, self.__tr("<b>Unable to open device %s.</b>"%(self.device_uri))) #self.close() return self.StaticTableWidget.clear() self.StaticTableWidget.setColumnCount(len(self.headers)) self.StaticTableWidget.setHorizontalHeaderLabels(self.headers) mq_keys = list(d.mq.keys()) mq_keys.sort() self.StaticTableWidget.setRowCount(len(mq_keys)) for row, key in enumerate(mq_keys): i = QTableWidgetItem(QString(key)) i.setFlags(flags) self.StaticTableWidget.setItem(row, 0, i) i = QTableWidgetItem(QString(str(d.mq[key]))) i.setFlags(flags) self.StaticTableWidget.setItem(row, 1, i) self.StaticTableWidget.resizeColumnToContents(0) self.StaticTableWidget.resizeColumnToContents(1) self.StaticTableWidget.setSortingEnabled(True) self.StaticTableWidget.sortItems(0) # # Dynamic Data # try: try: d.open() d.queryDevice() except Error as e: QApplication.restoreOverrideCursor() FailureUI(self, self.__tr("<b>Unable to open device %s.</b>"%(self.device_uri))) #self.close() return dq_keys = list(d.dq.keys()) dq_keys.sort() self.DynamicTableWidget.setRowCount(len(dq_keys)) for row, key in enumerate(dq_keys): i = QTableWidgetItem(QString(key)) i.setFlags(flags) self.DynamicTableWidget.setItem(row, 0, i) i = QTableWidgetItem(QString(str(d.dq[key]))) i.setFlags(flags) self.DynamicTableWidget.setItem(row, 1, i) self.DynamicTableWidget.resizeColumnToContents(0) self.DynamicTableWidget.resizeColumnToContents(1) self.DynamicTableWidget.setSortingEnabled(True) self.DynamicTableWidget.sortItems(0) finally: d.close() # # History Table # self.HistoryTableWidget.clear() self.HistoryTableWidget.setRowCount(0) if d.device_type == DEVICE_TYPE_FAX: self.history_headers[1] = self.__tr("Fax") else: self.history_headers[1] = self.__tr("Printer") self.HistoryTableWidget.setColumnCount(len(self.history_headers)) self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers) history = d.queryHistory() history.reverse() self.HistoryTableWidget.setRowCount(len(history)) for row, h in enumerate(history): dt = QDateTime() dt.setTime_t(int(h.timedate)) dt = value_str(dt) ess = device.queryString(h.event_code, 0) for col, t in enumerate([dt, h.printer_name, to_unicode(h.event_code), ess, h.username, to_unicode(h.job_id), h.title]): i = QTableWidgetItem(QString(t)) i.setFlags(flags) self.HistoryTableWidget.setItem(row, col, i) self.HistoryTableWidget.resizeColumnToContents(0) self.HistoryTableWidget.resizeColumnToContents(1) self.HistoryTableWidget.setSortingEnabled(True) self.HistoryTableWidget.sortItems(0) # # Printer Data # printers = cups.getPrinters() for p in printers: if p.device_uri == self.device_uri: Tab = QWidget() Tab.setObjectName(QString(p.name)) GridLayout = QGridLayout(Tab) GridLayout.setObjectName(QString("GridLayout-%s" % p.name)) Table = QTableWidget(Tab) Table.setAlternatingRowColors(True) Table.setSelectionMode(QAbstractItemView.SingleSelection) Table.setSelectionBehavior(QAbstractItemView.SelectRows) Table.setVerticalScrollMode(QAbstractItemView.ScrollPerItem) Table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) Table.setGridStyle(Qt.DotLine) Table.setObjectName(QString("Table-%s" % p.name)) GridLayout.addWidget(Table, 0, 0, 1, 1) self.TabWidget.addTab(Tab, QString(p.name)) Table.setColumnCount(len(self.headers)) Table.setHorizontalHeaderLabels(self.headers) cups.resetOptions() cups.openPPD(p.name) current_options = dict(cups.getOptions()) #current_options['cups_error_log_level'] = cups.getErrorLogLevel() try: f = open(os.path.expanduser('~/.cups/lpoptions')) except IOError as e: log.debug(str(e)) current_options['lpoptions_file_data'] = QString("(%s)"%str(e)) else: text = f.read() for d in text.splitlines(): if p.name in d: current_options['lpoptions_file_data'] = d break else: current_options['lpoptions_file_data'] = self.__tr("(no data)") keys = list(current_options.keys()) keys.sort() Table.setRowCount(len(keys)) for row, key in enumerate(keys): i = QTableWidgetItem(QString(key)) i.setFlags(flags) Table.setItem(row, 0, i) if key == 'printer-state': state = int(current_options[key]) if state == cups.IPP_PRINTER_STATE_IDLE: i = QTableWidgetItem(self.__tr("idle (%s)"%state)) elif state == cups.IPP_PRINTER_STATE_PROCESSING: i = QTableWidgetItem(self.__tr("busy/printing (%s)"%state)) elif state == cups.IPP_PRINTER_STATE_STOPPED: i = QTableWidgetItem(self.__tr("stopped (%s)"%state)) else: i = QTableWidgetItem(QString(str(state))) else: i = QTableWidgetItem(QString(str(current_options[key]))) i.setFlags(flags) Table.setItem(row, 1, i) Table.resizeColumnToContents(0) Table.resizeColumnToContents(1) Table.setSortingEnabled(True) Table.sortItems(0) cups.closePPD() self.TabWidget.setCurrentIndex(0) QApplication.restoreOverrideCursor()
def updateInfoTable(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.DynamicTableWidget.clear() self.DynamicTableWidget.setRowCount(0) self.DynamicTableWidget.setColumnCount(0) flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled while self.TabWidget.count() > 3: self.TabWidget.removeTab(3) self.DynamicTableWidget.clear() self.DynamicTableWidget.setRowCount(0) self.DynamicTableWidget.setColumnCount(len(self.headers)) self.DynamicTableWidget.setHorizontalHeaderLabels(self.headers) # # Static Data # try: d = device.Device(self.device_uri, None) except Error: QApplication.restoreOverrideCursor() FailureUI( self, self.__tr("<b>Unable to open device %s.</b>" % (self.device_uri))) #self.close() return self.StaticTableWidget.clear() self.StaticTableWidget.setColumnCount(len(self.headers)) self.StaticTableWidget.setHorizontalHeaderLabels(self.headers) mq_keys = list(d.mq.keys()) mq_keys.sort() self.StaticTableWidget.setRowCount(len(mq_keys)) for row, key in enumerate(mq_keys): i = QTableWidgetItem(str(key)) i.setFlags(flags) self.StaticTableWidget.setItem(row, 0, i) i = QTableWidgetItem(str(d.mq[key])) i.setFlags(flags) self.StaticTableWidget.setItem(row, 1, i) self.StaticTableWidget.resizeColumnToContents(0) self.StaticTableWidget.resizeColumnToContents(1) self.StaticTableWidget.setSortingEnabled(True) self.StaticTableWidget.sortItems(0) # # Dynamic Data # try: try: d.open() d.queryDevice() except Error as e: QApplication.restoreOverrideCursor() FailureUI( self, self.__tr("<b>Unable to open device %s.</b>" % (self.device_uri))) #self.close() return dq_keys = list(d.dq.keys()) dq_keys.sort() self.DynamicTableWidget.setRowCount(len(dq_keys)) for row, key in enumerate(dq_keys): i = QTableWidgetItem(str(key)) i.setFlags(flags) self.DynamicTableWidget.setItem(row, 0, i) i = QTableWidgetItem(str(d.dq[key])) i.setFlags(flags) self.DynamicTableWidget.setItem(row, 1, i) self.DynamicTableWidget.resizeColumnToContents(0) self.DynamicTableWidget.resizeColumnToContents(1) self.DynamicTableWidget.setSortingEnabled(True) self.DynamicTableWidget.sortItems(0) finally: d.close() # # History Table # self.HistoryTableWidget.clear() self.HistoryTableWidget.setRowCount(0) if d.device_type == DEVICE_TYPE_FAX: self.history_headers[1] = self.__tr("Fax") else: self.history_headers[1] = self.__tr("Printer") self.HistoryTableWidget.setColumnCount(len(self.history_headers)) self.HistoryTableWidget.setHorizontalHeaderLabels(self.history_headers) history = d.queryHistory() history.reverse() self.HistoryTableWidget.setRowCount(len(history)) for row, h in enumerate(history): dt = QDateTime() dt.setTime_t(int(h.timedate)) dt = value_str(dt) ess = device.queryString(h.event_code, 0) for col, t in enumerate([ dt, h.printer_name, to_unicode(h.event_code), ess, h.username, to_unicode(h.job_id), h.title ]): i = QTableWidgetItem(str(t)) i.setFlags(flags) self.HistoryTableWidget.setItem(row, col, i) self.HistoryTableWidget.resizeColumnToContents(0) self.HistoryTableWidget.resizeColumnToContents(1) self.HistoryTableWidget.setSortingEnabled(True) self.HistoryTableWidget.sortItems(0) # # Printer Data # printers = cups.getPrinters() for p in printers: if p.device_uri == self.device_uri: Tab = QWidget() Tab.setObjectName(str(p.name)) GridLayout = QGridLayout(Tab) GridLayout.setObjectName(str("GridLayout-%s" % p.name)) Table = QTableWidget(Tab) Table.setAlternatingRowColors(True) Table.setSelectionMode(QAbstractItemView.SingleSelection) Table.setSelectionBehavior(QAbstractItemView.SelectRows) Table.setVerticalScrollMode(QAbstractItemView.ScrollPerItem) Table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) Table.setGridStyle(Qt.DotLine) Table.setObjectName(str("Table-%s" % p.name)) GridLayout.addWidget(Table, 0, 0, 1, 1) self.TabWidget.addTab(Tab, str(p.name)) Table.setColumnCount(len(self.headers)) Table.setHorizontalHeaderLabels(self.headers) cups.resetOptions() cups.openPPD(p.name) current_options = dict(cups.getOptions()) #current_options['cups_error_log_level'] = cups.getErrorLogLevel() try: f = open(os.path.expanduser('~/.cups/lpoptions')) except IOError as e: log.debug(str(e)) current_options['lpoptions_file_data'] = str("(%s)" % str(e)) else: text = f.read() for d in text.splitlines(): if p.name in d: current_options['lpoptions_file_data'] = d break else: current_options['lpoptions_file_data'] = self.__tr( "(no data)") keys = list(current_options.keys()) keys.sort() Table.setRowCount(len(keys)) for row, key in enumerate(keys): i = QTableWidgetItem(str(key)) i.setFlags(flags) Table.setItem(row, 0, i) if key == 'printer-state': state = int(current_options[key]) if state == cups.IPP_PRINTER_STATE_IDLE: i = QTableWidgetItem(self.__tr("idle (%s)" % state)) elif state == cups.IPP_PRINTER_STATE_PROCESSING: i = QTableWidgetItem( self.__tr("busy/printing (%s)" % state)) elif state == cups.IPP_PRINTER_STATE_STOPPED: i = QTableWidgetItem( self.__tr("stopped (%s)" % state)) else: i = QTableWidgetItem(str(state)) else: i = QTableWidgetItem(str(current_options[key])) i.setFlags(flags) Table.setItem(row, 1, i) Table.resizeColumnToContents(0) Table.resizeColumnToContents(1) Table.setSortingEnabled(True) Table.sortItems(0) cups.closePPD() self.TabWidget.setCurrentIndex(0) QApplication.restoreOverrideCursor()
def addJobStorage(self, current_options=None): self.addJobStorageMode() self.addJobStoragePIN() self.addJobStorageUsername() self.addJobStorageID() self.addJobStorageIDExists() self.jobStorageDisable() if current_options is None: cups.resetOptions() cups.openPPD(self.cur_printer) current_options = dict(cups.getOptions()) cups.closePPD() self.job_storage_pin = unicode(current_options.get('HOLDKEY', '0000')[:4]) self.jobStoragePINEdit.setText(self.job_storage_pin) self.job_storage_username = unicode(current_options.get('USERNAME', prop.username)[:16]) self.jobStorageUsernameEdit.setText(self.job_storage_username) self.job_storage_jobname = unicode(current_options.get('JOBNAME', u"Untitled")[:16]) self.jobStorageIDEdit.setText(self.job_storage_jobname) hold = current_options.get('HOLD', 'OFF') holdtype = current_options.get('HOLDTYPE', 'PUBLIC') if hold == 'OFF': self.job_storage_mode = JOB_STORAGE_TYPE_OFF elif hold == 'ON': if holdtype == 'PUBLIC': self.job_storage_mode = JOB_STORAGE_TYPE_QUICK_COPY else: # 'PRIVATE' self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == 'PROOF': if holdtype == 'PUBLIC': self.job_storage_mode = JOB_STORAGE_TYPE_PROOF_AND_HOLD else: self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == 'STORE': self.job_storage_mode = JOB_STORAGE_TYPE_STORE self.job_storage_use_pin = (holdtype == 'PRIVATE') self.jobStorageModeComboBox.setCurrentItem(self.job_storage_mode) self.jobStorageModeDefaultPushButton.setEnabled(self.job_storage_mode != JOB_STORAGE_TYPE_OFF) self.setModeTooltip() self.setPrinterOptionHold() duplicate = current_options.get('DUPLICATEJOB', 'REPLACE') if duplicate == 'REPLACE': self.job_storage_job_exist = 0 else: self.job_storage_job_exist = 1 self.jobStorageIDExistsComboBox.setCurrentItem(self.job_storage_job_exist) self.setPrinterOptionIDExists() # if self.job_storage_mode == JOB_STORAGE_TYPE_OFF: self.jobStorageDisable() else: self.jobStorageUserJobEnable() self.setPrinterOptionID() self.setPrinterOptionPIN() self.setPrinterOptionUsername() self.jobStoragePINButtonGroup.setButton(self.job_storage_use_pin) self.jobStoragePINEnable(self.job_storage_mode in (JOB_STORAGE_TYPE_PERSONAL, JOB_STORAGE_TYPE_STORE))
def fillControls(self): QApplication.setOverrideCursor(QApplication.waitCursor) ScrollView.fillControls(self) self.loading = True cups.resetOptions() cups.openPPD(self.cur_printer) cur_outputmode = "" #if 1: try: if 1: #try: current_options = dict(cups.getOptions()) if not self.cur_device.device_type == DEVICE_TYPE_FAX: self.addGroupHeading("basic", self.__tr("Basic")) log.debug("Group: Basic") # Basic # PageSize (in PPD section) # orientation-requested # sides # outputorder # Collate current = current_options.get('orientation-requested', '3') self.addItem("basic", "orientation-requested", self.__tr("Page Orientation"), cups.PPD_UI_PICKONE, current, [('3', self.__tr('Portrait')), ('4', self.__tr('Landscape')), ('5', self.__tr('Reverse landscape')), ('6', self.__tr('Reverse portrait'))], '3') log.debug("Option: orientation-requested") log.debug("Current value: %s" % current) duplexer = self.cur_device.dq.get('duplexer', 0) log.debug("Duplexer = %d" % duplexer) if duplexer: current = current_options.get('sides', 'one-sided') self.addItem("basic", "sides", self.__tr("Duplex (Print on both sides of the page)"), cups.PPD_UI_PICKONE, current, [('one-sided',self.__tr('Single sided')), ('two-sided-long-edge', self.__tr('Two sided (long edge)')), ('two-sided-short-edge', self.__tr('Two sided (short edge)'))], 'one-sided') log.debug("Option: sides") log.debug("Current value: %s" % current) current = current_options.get('outputorder', 'normal') self.addItem("basic", "outputorder", self.__tr("Output Order (Print last page first)"), cups.PPD_UI_PICKONE, current, [('normal', self.__tr('Normal (Print first page first)')), ('reverse', self.__tr('Reversed (Print last page first)'))], 'normal') log.debug("Option: outputorder") log.debug("Current value: %s" % current) current = utils.to_bool(current_options.get('Collate', '0')) self.addItem("basic", "Collate", self.__tr("Collate (Group together multiple copies)"), cups.PPD_UI_BOOLEAN, current, [], 0) log.debug("Option: Collate") log.debug("Current value: %s" % current) groups = cups.getGroupList() for g in groups: log.debug("Group: %s" % repr(g)) if 'jobretention' in g.lower(): log.debug("HPJobRetention skipped.") continue text, num_subgroups = cups.getGroup(g) read_only = 'install' in g.lower() try: text = text.decode('utf-8') except UnicodeDecodeError: pass if g.lower() == 'printoutmode': text = self.__tr("Quality") self.addGroupHeading(g, text, read_only) log.debug(" Text: %s" % repr(text)) log.debug("Num subgroups: %d" % num_subgroups) options = cups.getOptionList(g) for o in options: log.debug(" Option: %s" % repr(o)) if 'pageregion' in o.lower(): log.debug("Page Region skipped.") continue option_text, defchoice, conflicted, ui = cups.getOption(g, o) try: option_text = option_text.decode('utf-8') except UnicodeDecodeError: pass if o.lower() == 'quality': option_text = self.__tr("Quality") log.debug(" Text: %s" % repr(option_text)) log.debug(" Defchoice: %s" % repr(defchoice)) choices = cups.getChoiceList(g, o) value = None choice_data = [] for c in choices: log.debug(" Choice: %s" % repr(c)) # TODO: Add custom paper size controls if 'pagesize' in o.lower() and 'custom' in c.lower(): log.debug("Skipped.") continue choice_text, marked = cups.getChoice(g, o, c) try: choice_text = choice_text.decode('utf-8') except UnicodeDecodeError: pass log.debug(" Text: %s" % repr(choice_text)) if marked: value = c choice_data.append((c, choice_text)) if o.lower() == 'outputmode': if value is not None: cur_outputmode = value else: cur_outputmode = defchoice self.addItem(g, o, option_text, ui, value, choice_data, defchoice, read_only) ## if 'pagesize' in o.lower(): # and 'custom' in c.lower(): ## current = 0.0 ## width_widget = self.addItem("custom", "custom-width", self.__tr("Custom Paper Width"), cups.UI_UNITS_SPINNER, ## current, (0.0, 0.0), 0.0) ## ## current = 0.0 ## height_widget = self.addItem("custom", "custom-height", self.__tr("Custom Paper Height"), cups.UI_UNITS_SPINNER, ## current, (0.0, 0.0), 0.0) ## ## if value.lower() == 'custom': ## pass # N-Up # number-up # number-up-layout # page-border self.addGroupHeading("nup", self.__tr("N-Up (Multiple document pages per printed page)")) log.debug("Group: N-Up") current = current_options.get('number-up', '1') self.addItem("nup", "number-up", self.__tr("Pages per Sheet"), cups.PPD_UI_PICKONE, current, [('1', self.__tr('1 page per sheet')), ('2', self.__tr('2 pages per sheet')), ('4', self.__tr('4 pages per sheet'))], '1') log.debug(" Option: number-up") log.debug(" Current value: %s" % current) current = current_options.get('number-up-layout', 'lrtb') self.addItem("nup", "number-up-layout", self.__tr("Layout"), cups.PPD_UI_PICKONE, current, [('btlr', self.__tr('Bottom to top, left to right')), ('btrl', self.__tr('Bottom to top, right to left')), ('lrbt', self.__tr('Left to right, bottom to top')), ('lrtb', self.__tr('Left to right, top to bottom')), ('rlbt', self.__tr('Right to left, bottom to top')), ('rltb', self.__tr('Right to left, top to bottom')), ('tblr', self.__tr('Top to bottom, left to right')), ('tbrl', self.__tr('Top to bottom, right to left')) ], 'lrtb') log.debug(" Option: number-up-layout") log.debug(" Current value: %s" % current) current = current_options.get('page-border', 'none') self.addItem("nup", "page-border", self.__tr("Printed Border Around Each Page"), cups.PPD_UI_PICKONE, current, [('double', self.__tr("Two thin borders")), ("double-thick", self.__tr("Two thick borders")), ("none", self.__tr("No border")), ("single", self.__tr("One thin border")), ("single-thick", self.__tr("One thick border"))], 'none') log.debug(" Option: page-border") log.debug(" Current value: %s" % current) # Adjustment # brightness # gamma if not self.cur_device.device_type == DEVICE_TYPE_FAX: self.addGroupHeading("adjustment", self.__tr("Printout Appearance")) current = int(current_options.get('brightness', 100)) log.debug(" Option: brightness") log.debug(" Current value: %s" % current) self.addItem("adjustment", "brightness", self.__tr("Brightness"), cups.UI_SPINNER, current, (0, 200), 100, suffix=" %") current = int(current_options.get('gamma', 1000)) log.debug(" Option: gamma") log.debug(" Current value: %s" % current) self.addItem("adjustment", "gamma", self.__tr("Gamma"), cups.UI_SPINNER, current, (1, 10000), 1000) # Margins (pts) # page-left # page-right # page-top # page-bottom ## if 0: ## # TODO: cupsPPDPageSize() fails on LaserJets. How do we get margins in this case? Defaults? ## # PPD file for LJs has a HWMargin entry... ## page, page_width, page_len, left, bottom, right, top = cups.getPPDPageSize() ## ## right = page_width - right ## top = page_len - top ## ## self.addGroupHeading("margins", self.__tr("Margins")) ## current_top = current_options.get('page-top', 0) # pts ## current_bottom = current_options.get('page-bottom', 0) # pts ## current_left = current_options.get('page-left', 0) # pts ## current_right = current_options.get('page-right', 0) # pts ## ## log.debug(" Option: page-top") ## log.debug(" Current value: %s" % current_top) ## ## self.addItem("margins", "page-top", self.__tr("Top margin"), ## cups.UI_UNITS_SPINNER, current_top, ## (0, page_len), top) ## ## self.addItem("margins", "page-bottom", self.__tr("Bottom margin"), ## cups.UI_UNITS_SPINNER, current_bottom, ## (0, page_len), bottom) ## ## self.addItem("margins", "page-left", self.__tr("Right margin"), ## cups.UI_UNITS_SPINNER, current_left, ## (0, page_width), left) ## ## self.addItem("margins", "page-right", self.__tr("Left margin"), ## cups.UI_UNITS_SPINNER, current_right, ## (0, page_width), right) # Image Printing # position # natural-scaling # saturation # hue self.addGroupHeading("image", self.__tr("Image Printing")) current = utils.to_bool(current_options.get('fitplot', 'false')) self.addItem("image", "fitplot", self.__tr("Fit to Page"), cups.PPD_UI_BOOLEAN, current, [], 0) current = current_options.get('position', 'center') self.addItem("image", "position", self.__tr("Position on Page"), cups.PPD_UI_PICKONE, current, [('center', self.__tr('Centered')), ('top', self.__tr('Top')), ('left', self.__tr('Left')), ('right', self.__tr('Right')), ('top-left', self.__tr('Top left')), ('top-right', self.__tr('Top right')), ('bottom', self.__tr('Bottom')), ('bottom-left', self.__tr('Bottom left')), ('bottom-right', self.__tr('Bottom right'))], 'center') log.debug(" Option: position") log.debug(" Current value: %s" % current) if not self.cur_device.device_type == DEVICE_TYPE_FAX: current = int(current_options.get('saturation', 100)) log.debug(" Option: saturation") log.debug(" Current value: %s" % current) self.addItem("image", "saturation", self.__tr("Saturation"), cups.UI_SPINNER, current, (0, 200), 100, suffix=" %") current = int(current_options.get('hue', 0)) log.debug(" Option: hue") log.debug(" Current value: %s" % current) self.addItem("image", "hue", self.__tr("Hue (color shift/rotation)"), cups.UI_SPINNER, current, (-100, 100), 0) current = int(current_options.get('natural-scaling', 100)) log.debug(" Option: natural-scaling") log.debug(" Current value: %s" % current) self.addItem("image", "natural-scaling", self.__tr('"Natural" Scaling (relative to image)'), cups.UI_SPINNER, current, (1, 800), 100, suffix=" %") current = int(current_options.get('scaling', 100)) log.debug(" Option: scaling") log.debug(" Current value: %s" % current) self.addItem("image", "scaling", self.__tr("Scaling (relative to page)"), cups.UI_SPINNER, current, (1, 800), 100, suffix=" %") # Misc # PrettyPrint # job-sheets # mirror self.addGroupHeading("misc", self.__tr("Miscellaneous")) log.debug("Group: Misc") current = utils.to_bool(current_options.get('prettyprint', '0')) self.addItem("misc", "prettyprint", self.__tr('"Pretty Print" Text Documents (Add headers and formatting)'), cups.PPD_UI_BOOLEAN, current, [], 0) log.debug(" Option: prettyprint") log.debug(" Current value: %s" % current) if not self.cur_device.device_type == DEVICE_TYPE_FAX: current = current_options.get('job-sheets', 'none').split(',') try: start = current[0] except IndexError: start = 'none' try: end = current[1] except IndexError: end = 'none' # TODO: Look for locally installed banner pages beyond the default CUPS ones? self.addItem("misc", "job-sheets", self.__tr("Banner Pages"), cups.UI_BANNER_JOB_SHEETS, (start, end), [("none", self.__tr("No banner page")), ('classified', self.__tr("Classified")), ('confidential', self.__tr("Confidential")), ('secret', self.__tr("Secret")), ('standard', self.__tr("Standard")), ('topsecret', self.__tr("Top secret")), ('unclassified', self.__tr("Unclassified"))], ('none', 'none')) log.debug(" Option: job-sheets") log.debug(" Current value: %s,%s" % (start, end)) current = utils.to_bool(current_options.get('mirror', '0')) self.addItem("misc", "mirror", self.__tr('Mirror Printing'), cups.PPD_UI_BOOLEAN, current, [], 0) log.debug(" Option: mirror") log.debug(" Current value: %s" % current) #Summary #color input #quality quality_attr_name = "OutputModeDPI" cur_outputmode_dpi = cups.findPPDAttribute(quality_attr_name, cur_outputmode) if cur_outputmode_dpi is not None: log.debug("Adding Group: Summary outputmode is : %s" % cur_outputmode) log.debug("Adding Group: Summary outputmode dpi is : %s" % str (cur_outputmode_dpi)) self.addGroupHeading("summry", self.__tr("Summary")) self.addItem("summry", "colorinput", self.__tr('Color Input / Black Render'), cups.UI_INFO, cur_outputmode_dpi, [], 0) self.addItem("summry", "quality", self.__tr('Print Quality'), cups.UI_INFO, cur_outputmode, [], 0) self.job_storage_avail = 0 #self.cur_device.mq['job-storage'] == JOB_STORAGE_ENABLE #print current_options if self.job_storage_avail: self.addGroupHeading("jobstorage", self.__tr("Job Storage and Secure Printing")) self.addJobStorage(current_options) #except Exception, e: #log.exception() # pass finally: cups.closePPD() self.loading = False QApplication.restoreOverrideCursor()
def processFile(self, path, title=''): # Process an arbitrary file ("Add file...") path = os.path.realpath(path) if not title: title = os.path.basename(path) if os.path.exists(path) and os.access(path, os.R_OK): mime_type = magic.mime_type(path) mime_type_desc = mime_type if mime_type == 'application/hplip-fax': mime_type_desc = self.MIME_TYPES_DESC[mime_type][0] fax_file_fd = file(path, 'r') header = fax_file_fd.read(fax.FILE_HEADER_SIZE) mg, version, pages, hort_dpi, vert_dpi, page_size, \ resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header) if mg != 'hplip_g3': log.error("Invalid file header. Bad magic.") self.form.WarningUI(self.__tr("<b>Invalid HPLIP Fax file.</b><p>Bad magic!")) return self.addFile(path, title, mime_type, mime_type_desc, pages) else: log.debug(repr(mime_type)) try: mime_type_desc = self.MIME_TYPES_DESC[mime_type][0] except KeyError: self.form.WarningUI(self.__tr("<b>You are trying to add a file that cannot be directly faxed with this utility.</b><p>To print this file, use the print command in the application that created it.")) return else: log.debug("Adding file: title='%s' file=%s mime_type=%s mime_desc=%s)" % (title, path, mime_type, mime_type_desc)) all_pages = True page_range = '' page_set = 0 #nup = 1 cups.resetOptions() self.cups_printers = cups.getPrinters() printer_state = cups.IPP_PRINTER_STATE_STOPPED for p in self.cups_printers: if p.name == self.cur_printer: printer_state = p.state log.debug("Printer state = %d" % printer_state) if printer_state == cups.IPP_PRINTER_STATE_IDLE: log.debug("Printing: %s on %s" % (path, self.cur_printer)) sent_job_id = cups.printFile(self.cur_printer, path, os.path.basename(path)) self.last_job_id = sent_job_id job_types[sent_job_id] = mime_type # save for later log.debug("Job ID=%d" % sent_job_id) QApplication.setOverrideCursor(QApplication.waitCursor) self.waitdlg = WaitForm(0, self.__tr("Processing fax file..."), None, self, modal=1) # self.add_fax_canceled self.waitdlg.show() else: self.form.FailureUI(self.__tr("<b>Printer '%1' is in a stopped or error state.</b><p>Check the printer queue in CUPS and try again.").arg(self.cur_printer)) cups.resetOptions() return cups.resetOptions() QApplication.restoreOverrideCursor() else: 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))
def addJobStorage(self, current_options=None): self.addJobStorageMode() self.addJobStoragePIN() self.addJobStorageUsername() self.addJobStorageID() self.addJobStorageIDExists() self.jobStorageDisable() if current_options is None: cups.resetOptions() cups.openPPD(self.cur_printer) current_options = dict(cups.getOptions()) cups.closePPD() self.job_storage_pin = to_unicode( current_options.get('HOLDKEY', '0000')[:4]) self.jobStoragePINEdit.setText(self.job_storage_pin) self.job_storage_username = to_unicode( current_options.get('USERNAME', prop.username)[:16]) self.jobStorageUsernameEdit.setText(self.job_storage_username) self.job_storage_jobname = to_unicode( current_options.get('JOBNAME', "Untitled")[:16]) self.jobStorageIDEdit.setText(self.job_storage_jobname) hold = current_options.get('HOLD', 'OFF') holdtype = current_options.get('HOLDTYPE', 'PUBLIC') if hold == 'OFF': self.job_storage_mode = JOB_STORAGE_TYPE_OFF elif hold == 'ON': if holdtype == 'PUBLIC': self.job_storage_mode = JOB_STORAGE_TYPE_QUICK_COPY else: # 'PRIVATE' self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == 'PROOF': if holdtype == 'PUBLIC': self.job_storage_mode = JOB_STORAGE_TYPE_PROOF_AND_HOLD else: self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == 'STORE': self.job_storage_mode = JOB_STORAGE_TYPE_STORE self.job_storage_use_pin = (holdtype == 'PRIVATE') self.jobStorageModeComboBox.setCurrentItem(self.job_storage_mode) self.jobStorageModeDefaultPushButton.setEnabled( self.job_storage_mode != JOB_STORAGE_TYPE_OFF) self.setModeTooltip() self.setPrinterOptionHold() duplicate = current_options.get('DUPLICATEJOB', 'REPLACE') if duplicate == 'REPLACE': self.job_storage_job_exist = 0 else: self.job_storage_job_exist = 1 self.jobStorageIDExistsComboBox.setCurrentItem( self.job_storage_job_exist) self.setPrinterOptionIDExists() # if self.job_storage_mode == JOB_STORAGE_TYPE_OFF: self.jobStorageDisable() else: self.jobStorageUserJobEnable() self.setPrinterOptionID() self.setPrinterOptionPIN() self.setPrinterOptionUsername() self.jobStoragePINButtonGroup.setButton(self.job_storage_use_pin) self.jobStoragePINEnable( self.job_storage_mode in (JOB_STORAGE_TYPE_PERSONAL, JOB_STORAGE_TYPE_STORE))
def addJobStorage(self, current_options=None): self.addJobStorageMode() self.addJobStoragePIN() self.addJobStorageUsername() self.addJobStorageID() self.addJobStorageIDExists() self.jobStorageDisable() if current_options is None: cups.resetOptions() cups.openPPD(self.cur_printer) current_options = dict(cups.getOptions()) cups.closePPD() self.job_storage_pin = to_unicode(current_options.get("HOLDKEY", "0000")[:4]) self.jobStoragePINEdit.setText(self.job_storage_pin) self.job_storage_username = to_unicode(current_options.get("USERNAME", prop.username)[:16]) self.jobStorageUsernameEdit.setText(self.job_storage_username) self.job_storage_jobname = to_unicode(current_options.get("JOBNAME", "Untitled")[:16]) self.jobStorageIDEdit.setText(self.job_storage_jobname) hold = current_options.get("HOLD", "OFF") holdtype = current_options.get("HOLDTYPE", "PUBLIC") if hold == "OFF": self.job_storage_mode = JOB_STORAGE_TYPE_OFF elif hold == "ON": if holdtype == "PUBLIC": self.job_storage_mode = JOB_STORAGE_TYPE_QUICK_COPY else: # 'PRIVATE' self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == "PROOF": if holdtype == "PUBLIC": self.job_storage_mode = JOB_STORAGE_TYPE_PROOF_AND_HOLD else: self.job_storage_mode = JOB_STORAGE_TYPE_PERSONAL self.job_storage_use_pin = True elif hold == "STORE": self.job_storage_mode = JOB_STORAGE_TYPE_STORE self.job_storage_use_pin = holdtype == "PRIVATE" self.jobStorageModeComboBox.setCurrentItem(self.job_storage_mode) self.jobStorageModeDefaultPushButton.setEnabled(self.job_storage_mode != JOB_STORAGE_TYPE_OFF) self.setModeTooltip() self.setPrinterOptionHold() duplicate = current_options.get("DUPLICATEJOB", "REPLACE") if duplicate == "REPLACE": self.job_storage_job_exist = 0 else: self.job_storage_job_exist = 1 self.jobStorageIDExistsComboBox.setCurrentItem(self.job_storage_job_exist) self.setPrinterOptionIDExists() # if self.job_storage_mode == JOB_STORAGE_TYPE_OFF: self.jobStorageDisable() else: self.jobStorageUserJobEnable() self.setPrinterOptionID() self.setPrinterOptionPIN() self.setPrinterOptionUsername() self.jobStoragePINButtonGroup.setButton(self.job_storage_use_pin) self.jobStoragePINEnable(self.job_storage_mode in (JOB_STORAGE_TYPE_PERSONAL, JOB_STORAGE_TYPE_STORE))