def run(self): tmp = QTemporaryFile() result = {} io = None dssp = None prevChain = None key = None if tmp.open(): io = PDBIO() io.set_structure(self.struct) io.save(tmp.fileName()) try: dssp = DSSP(self.struct[0], tmp.fileName(), dssp='mkdssp') prevChain = next(iter(dssp.keys()))[0] for key in dssp.keys(): #print(key[0]) if key[0] == prevChain: #print(key) # I THINK I'M DOING THIS PART WRONG result[dssp[key][0] + self.offset] = dssp[key][2] self.finished.emit([result, self.seq, self.node]) except: traceback.print_exc() print("SORRY, DSSP WAS NOT FOUND") self.finished.emit([None, None, None]) del tmp, result, io, dssp, prevChain, key
def capture(source: str, frametime: str, thumbsize: ThumbSize = ThumbSize.INDEX, external: bool = False) -> QPixmap: capres = QPixmap() img = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX.jpg')) if img.open(): imagecap = img.fileName() size = thumbsize.value backend, _ = VideoService.initBackends() args = '-hide_banner -ss %s -i "%s" -vframes 1 -s %ix%i -v 16 -y "%s"' % ( frametime, source, size.width(), size.height(), imagecap) proc = VideoService.initProc() proc.setProcessChannelMode(QProcess.MergedChannels) if proc.state() == QProcess.NotRunning: if os.getenv('DEBUG', False): logging.getLogger(__name__).info('"%s %s"' % (backend, args)) proc.start(backend, shlex.split(args)) proc.waitForFinished(-1) if proc.exitStatus() == QProcess.NormalExit and proc.exitCode( ) == 0: capres = QPixmap(imagecap, 'JPG') if external: painter = QPainter(capres) painter.drawPixmap(0, 0, QPixmap(':/images/external.png', 'PNG')) painter.end() img.remove() return capres
def display_downloaded_content(self): """Open downloaded non-html content in a separate application. Called when an unsupported content type is finished downloading. """ file_path = ( QDir.toNativeSeparators( QDir.tempPath() + "/XXXXXX_" + self.content_filename ) ) myfile = QTemporaryFile(file_path) myfile.setAutoRemove(False) if myfile.open(): myfile.write(self.reply.readAll()) myfile.close() subprocess.Popen([ (self.config.get("content_handlers") .get(str(self.content_type))), myfile.fileName() ]) # Sometimes downloading files opens an empty window. # So if the current window has no URL, close it. if(str(self.url().toString()) in ('', 'about:blank')): self.close()
def captureFrame(settings: QSettings, source: str, frametime: str, thumbsize: QSize = None, external: bool = False) -> QPixmap: if thumbsize is None: thumbsize = VideoService.config.thumbnails['INDEX'] capres = QPixmap() img = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX.jpg')) if img.open(): imagecap = img.fileName() cmd = VideoService.findBackends(settings).ffmpeg tsize = '{0:d}x{1:d}'.format(thumbsize.width(), thumbsize.height()) args = '-hide_banner -ss {frametime} -i "{source}" -vframes 1 -s {tsize} -y "{imagecap}"'.format( **locals()) proc = VideoService.initProc() if proc.state() == QProcess.NotRunning: proc.start(cmd, shlex.split(args)) proc.waitForFinished(-1) if proc.exitStatus() == QProcess.NormalExit and proc.exitCode( ) == 0: capres = QPixmap(imagecap, 'JPG') if external: painter = QPainter(capres) painter.drawPixmap(0, 0, QPixmap(':/images/external.png', 'PNG')) painter.end() img.remove() return capres
def display_downloaded_content(self): """Open downloaded non-html content in a separate application. Called when an unsupported content type is finished downloading. """ debug("displaying downloaded content from {}".format(self.reply.url())) file_path = ( QDir.toNativeSeparators( QDir.tempPath() + "/XXXXXX_" + self.content_filename ) ) myfile = QTemporaryFile(file_path) myfile.setAutoRemove(False) if myfile.open(): myfile.write(self.reply.readAll()) myfile.close() subprocess.Popen([ (self.config.get("content_handlers") .get(str(self.content_type))), myfile.fileName() ]) # Sometimes downloading files opens an empty window. # So if the current window has no URL, close it. if(str(self.url().toString()) in ('', 'about:blank')): self.close()
def testJoin(self, file1: str, file2: str) -> bool: result = False self.logger.info('attempting to test joining of "%s" + "%s"' % (file1, file2)) try: # 1. check audio + video codecs file1_codecs = self.codecs(file1) file2_codecs = self.codecs(file2) if file1_codecs != file2_codecs: self.logger.info('join test failed for %s and %s: codecs mismatched' % (file1, file2)) self.lastError = '<p>The audio + video format of this media file is not the same as the files ' + \ 'already in your clip index.</p>' + \ '<div align="center">Current files are <b>{0}</b> (video) and ' + \ '<b>{1}</b> (audio)<br/>' + \ 'Failed media is <b>{2}</b> (video) and <b>{3}</b> (audio)</div>' self.lastError = self.lastError.format(file1_codecs[0], file1_codecs[1], file2_codecs[0], file2_codecs[1]) return result # 2. check frame sizes size1 = self.framesize(file1) size2 = self.framesize(file2) if size1 != size2: self.logger.info('join test failed for %s and %s: frame size mismatched' % (file1, file2)) self.lastError = '<p>The frame size of this media file is not the same as the files already in ' + \ 'your clip index.</p>' + \ '<div align="center">Current media clips are <b>{0}x{1}</b>' + \ '<br/>Failed media file is <b>{2}x{3}</b></div>' self.lastError = self.lastError.format(size1.width(), size1.height(), size2.width(), size2.height()) return result # 2. generate temporary file handles _, ext = os.path.splitext(file1) file1_cut = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX%s' % ext)) file2_cut = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX%s' % ext)) final_join = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX%s' % ext)) # 3. produce 2 seconds long clips from input files for join test if file1_cut.open() and file2_cut.open() and final_join.open(): result1 = self.cut(file1, file1_cut.fileName(), '00:00:00.000', '00:00:04.00', False) result2 = self.cut(file2, file2_cut.fileName(), '00:00:00.000', '00:00:04.00', False) if result1 and result2: # 4. attempt join of temp 2 second clips result = self.join([file1_cut.fileName(), file2_cut.fileName()], final_join.fileName(), False) file1_cut.remove() file2_cut.remove() final_join.remove() except: self.logger.exception('Exception in VideoService.testJoin', exc_info=True) result = False return result
def run(self): """ 代码检测工作函数 """ while 1: if not self._running: logger.info('code checker quit') break if not self.background_checking: QThread.msleep(500) continue if self._queue.qsize() == 0: QThread.msleep(500) continue try: widget, code = self._queue.get(False, 0.5) # 创建临时文件 file = QTemporaryFile(self) file.setAutoRemove(True) if file.open(): with open(file.fileName(), 'wb') as fp: fp.write(code.encode()) file.close() # 使用flake8检测代码 results = [] with StringIO() as out, redirect_stdout(out): app = Application() app.initialize( ['flake8', '--exit-zero', '--config', os.path.join(os.path.dirname(__file__), 'config', '.flake8')]) app.run_checks([file.fileName()]) app.report() results = out.getvalue().split('\n') results = [ret for ret in results if re.search(r'\d+:\d+:[EFW]\d+:.*?', ret)] # if results: self.checked.emit(widget, results) # 如果为空,也应该这样做。将空列表传入可以清空所有的标记。 file.deleteLater() del file except Exception as e: logger.warning(str(e))
def capture(self, source: str, frametime: str) -> QPixmap: img, capres = None, QPixmap() try: img = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX.jpg')) if img.open(): imagecap = img.fileName() args = '-ss %s -i "%s" -vframes 1 -s 100x70 -y %s' % ( frametime, source, imagecap) if self.cmdExec(self.backend, args): capres = QPixmap(imagecap, 'JPG') finally: del img return capres
def test_readColorSchemeFromFile(self): tempFile = QTemporaryFile('XXXXXX.colorscheme') tempFile.open(QTemporaryFile.WriteOnly) stream = QTextStream(tempFile) stream << 'htmltags = green\n' stream << 'htmlsymbols=#ff8800\n' stream << 'foo bar\n' stream << 'htmlcomments = #abc\n' tempFile.close() fileName = tempFile.fileName() colorScheme = readColorSchemeFromFile(fileName) self.assertEqual(colorScheme[0], QColor(0x00, 0x80, 0x00)) self.assertEqual(colorScheme[1], QColor(0xff, 0x88, 0x00)) self.assertEqual(colorScheme[2], Qt.darkYellow) # default self.assertEqual(colorScheme[3], QColor(0xaa, 0xbb, 0xcc))
def soffice_convert(page_id, format, new_filename, ui=None): res = build_odt(page_id) ext = "." + format.split(":")[0] soffice = find_soffice(ui) from mycartable.defaults.files_path import TMP temp = QTemporaryFile(str(TMP / uuid.uuid4().hex)) temp.open() p = Path(temp.fileName()) p.write_bytes(res.encode()) proc = subprocess.run( [soffice, "--headless", "--convert-to", format, str(p)], cwd=p.parent, capture_output=True, ) converted = p.parent / (p.stem + ext) new_path = Path(p.parent, new_filename) converted.replace(new_path) temp.close() return new_path
class EditorWorker(QObject): file_change_sig = pyqtSignal(bool) # is_zim def __init__(self, command, old_text, is_zim, zim_folder=None, docid=None, zim_file=None, parent=None): '''Observe the write/save states of a txt file to edit notes Args: command (list): command string list to pass into Popen. old_text (str): existing note text to paste into editor. is_zim (bool): if True, try open the associated zim note file. if False, open a temp file to edit. Kwargs: zim_folder (str or None): if not None, the path to the zim note folder, used to search for zim notes. docid (int or None): if not None, id of current doc. parent (QWidget or None): parent widget. ''' super(EditorWorker, self).__init__(parent) self.is_zim = is_zim self.zim_folder = zim_folder self.docid = docid self.logger = logging.getLogger(__name__) if not self.is_zim: self._temp_file = QTemporaryFile(self) else: if zim_file is not None: # use given zim file if os.path.exists(zim_file) and os.path.islink(zim_file): self._temp_file = QFile(zim_file, self) self.logger.debug('Got given zim file %s' % zim_file) else: try: zim_file = locateZimNote(self.zim_folder, self.docid) self._temp_file = QFile(zim_file, self) self.logger.exception( 'Failed to open given zim file. Get the id one.') except: self.logger.exception('Failed to find zim file.') self._temp_file = QTemporaryFile(self) self.is_zim = False else: # no given zim file, get the one in all_notes try: zim_file = locateZimNote(self.zim_folder, self.docid) self._temp_file = QFile(zim_file, self) self.logger.debug('Got zim file %s' % zim_file) except: self.logger.exception('Failed to find zim file.') self._temp_file = QTemporaryFile(self) self.is_zim = False self._process = QProcess(self) self._text = "" self._watcher = QFileSystemWatcher(self) self._watcher.fileChanged.connect(self.onFileChange) # write existing lines if temp file if not self.is_zim and self._temp_file.open(): self._temp_file.write(old_text.encode('utf-8')) self._temp_file.close() # open() on temp file assumes QIODevice.ReadWrite as well. if self._temp_file.open(QIODevice.ReadWrite): self._file_path = self._temp_file.fileName() self._watcher.addPath(self._file_path) self.logger.debug('_file_path = %s' % self._file_path) program = command[0] arguments = command[1:] self._process.start(program, arguments + [self._temp_file.fileName()]) @pyqtSlot() def onFileChange(self): if self._temp_file.isOpen(): #self._temp_file.seek(0) #self._text = self._temp_file.readAll().data().decode() # has to use with open and read(), the above doesn't work for # some editors, like xed # For some reason, if watching the zim file, and open in gvim # it reports file not found unless I wait for a while. wtf = os.path.exists(self._temp_file.fileName()) while not wtf: wtf = os.path.exists(self._temp_file.fileName()) with open(self._temp_file.fileName()) as tmp: self._text = tmp.read() # Re-add watch file, again for xed. self._watcher.removePath(self._file_path) self._watcher.addPath(self._file_path) self.file_change_sig.emit(self.is_zim) @property def text(self): return self._text def __del__(self): self._process.kill()
def save(self, parent, filename=None): """Saves the current file and sets is_modified to False. If the file has never been saved (i.e., doesn't have a filename) or is not writable, this method calls save_as. :type parent: QWidget - The parent window for dialogs, alerts, etc. :type filename: str - Full path of file or None (the default) :rtype: bool - True = Successfully saved file, False = error (user was notified) or user cancelled """ if filename is None: filename = self.filename # If the current file has never been saved... if filename is None: # ...call save_as instead self.on_file_saveas() wavfile = QFile(filename) # If the original file exists, but can't be opened for writing... if wavfile.exists() and not wavfile.open(QIODevice.ReadWrite): # ...then treat this as a Save-As command return self.save_as(parent) tmpfile = QTemporaryFile(filename) # If we can't open our temporary file for writing... if not QTemporaryFile.open(QIODevice.WriteOnly): # ...something's wrong (disk full?), so report it to the user and exit QMessageBox.critical( parent, make_caption('Warning'), "Unable to create temporary file:\n\n\t<b>{}</b>\n\n\n{}". format(tmpfile.fileName(), tmpfile.errorString())) return False # If the original file exists... if wavfile.exists(): # ...set the temporary file permissions to match the original tmpfile.setPermissions(wavfile.permissions()) # Ignore errors elif sys.platform == 'win32': # ...otherwise (on Windows) use standard permissions tmpfile.setPermissions(QFile.WriteGroup | QFile.WriteOther) elif sys.platform.startswith('linux') or sys.platform.startswith( 'darwin'): # ...otherwise (on Linux) use the file mode creation mask for the current process tmpfile.setPermissions(self.umask_as_permission() & Document.PERMISSION_MASK) else: raise RuntimeError( 'Unsupported platform: ' + sys.platform) # TODO - check this at startup, not here tmpfile.close() # TODO - is this necessary? # Write out the WAV file try: with wave.open(tmpfile.fileName(), mode='wb') as wave_write: # Set the audio file properties wave_write.setnchannels(self.channels) wave_write.setsampwidth(self.bytes_per_sample) wave_write.setframerate(self.sampling_rate) wave_write.setnframes(self.frames) wave_write.setcomptype(None) # Write the contents of memory out to the file wave_write.writeframes(self.frames) except wave.Error as e: # An error occurred, notify user and return False QMessageBox.critical( parent, make_caption('Warning'), "Unable to write file:\n\n\t<b>{}</b>\n\n\n{}".format( tmpfile.fileName(), e.args[0])) return False # Data was written successfully to temp file, so inform QTemporaryFile not to remove it automatically; we're # going to rename it to the original file tmpfile.setAutoRemove(False) backup_filename = filename + '~' # Remove any previous backup QFile.remove(backup_filename) # Rename the original file to the backup name QFile.rename(filename, backup_filename) # Rename the temporary file to the original name if not tmpfile.rename(filename): # If anything goes wrong, rename the backup file back to the original name QFile.rename(backup_filename, filename) QMessageBox.critical( parent, make_caption('Warning'), "Unable to rename file:\n\n\tFrom: <b>{}</b>\n\tTo: <b>{}</b>\n\n\n{}" .format(backup_filename, filename, tmpfile.errorString())) return False settings = QSettings() if not settings.value( Settings.CREATE_BACKUP_ON_SAVE, defaultValue=Settings.CREATE_BACKUP_ON_SAVE_DFLT): QFile.remove(backup_filename) self.is_modified = False self._set_filename(filename) return True
def run(self): returned = [] # TODO: Should pop up modal if not confident in the structure results! index = None pid = None struct = None structseq = None uniID = None alignoff = 0 result = None ids = [] coordinates = None line = None i = 0 x = None data = None structs = None struct0 = None offset = 0 start = None end = None parser = None tmp = None url = None myfile = None for seq in self.seqs: if self.nodes: index = self.nodes[self.seqs.index(seq)] pid = seq.id self.PDBLogger.info("Searching with ID %s" % pid) self.logger.emit("Searching with ID %s" % pid) uniID = self.u.search(pid, columns="id, genes, organism, protein names") if uniID: self.PDBLogger.info('Results!\n\n%s' % uniID) self.logger.emit('Results collected for search: %s' % uniID) result = uniID.split("\n") for line in result[1:]: ids.append(line.split("\t")) while coordinates == None: self.PDBLogger.info('Attempting search with %s from %s' % (ids[i][1], ids[i][2])) self.logger.emit('Attempting search with %s from %s' % (ids[i][1], ids[i][2])) structurl = "https://swissmodel.expasy.org/repository/uniprot/%s.json" % ids[ i][0] self.PDBLogger.debug( 'Searching SwissModel repository: %s' % structurl) self.logger.emit('Searching SwissModel for structure') try: with urllib.request.urlopen(structurl) as url: data = json.loads(url.read().decode()) if data['result']: #print("Data found") result = data['result'] if result['structures']: #print("structures found") structs = result['structures'] structseq = result['sequence'] self.PDBLogger.info( "QUERY: \n%s" % str(seq.seq).replace("-", "")) self.PDBLogger.info("RESULT: \n%s" % structseq) if str(seq.seq).replace("-", "") == structseq: # They should match, else keep looking if structs[0]: # print("accessing first model") struct0 = structs[0] if struct0['coordinates']: coordinates = struct0[ 'coordinates'] alignoff = int( struct0['chains']['A'][0] ['uniprot']['from']) - 1 self.PDBLogger.debug( "MODEL ACQUIRED") self.logger.emit('MODEL ACQUIRED!') else: i += 1 continue else: i += 1 continue else: self.PDBLogger.debug( "Seq didn't match, trying with next model" ) i += 1 continue else: i += 1 continue elif i == len(ids): self.PDBLogger.info("Sorry, no models found") break else: i += 1 continue except HTTPError: break if coordinates: start = structseq[:7] #print(start) for x in range(len(seq)): end = x + 7 if str(seq.seq)[x:end] == start: self.PDBLogger.debug( "Sequence offset is %s residues" % x) offset = x + alignoff self.PDBLogger.info( "Alignment offset is %s residues" % offset) self.logger.emit( "Alignment offset is %s residues" % offset) parser = PDB.PDBParser() tmp = QTemporaryFile() with urllib.request.urlopen(coordinates) as url: myfile = url.read() if tmp.open(): tmp.write(myfile) struct = parser.get_structure( ids[1], tmp.fileName()) self.PDBLogger.debug("STRUCTURE PARSED") self.logger.emit("STRUCTURE PARSED") #print(struct, type(struct)) returned.append([struct, seq, index, offset]) else: self.PDBLogger.debug("Sorry, no models found!!!") else: self.PDBLogger.info("NO STRUCTURE FOUND") self.logger.emit("No structure found, sorry!") self.finished.emit(returned) del returned, index, uniID, result, ids, line, coordinates, i, x, url, start, offset, tmp, parser, seq, struct, structseq, alignoff
def save(self): """ Public slot to save the history entries to disk. """ historyFile = QFile(self.getFileName()) if not historyFile.exists(): self.__lastSavedUrl = "" saveAll = self.__lastSavedUrl == "" first = len(self.__history) - 1 if not saveAll: # find the first one to save for index in range(len(self.__history)): if self.__history[index].url == self.__lastSavedUrl: first = index - 1 break if first == len(self.__history) - 1: saveAll = True if saveAll: # use a temporary file when saving everything f = QTemporaryFile() f.setAutoRemove(False) opened = f.open() else: f = historyFile opened = f.open(QIODevice.Append) if not opened: E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Unable to open history file <b>{0}</b>.<br/>""" """Reason: {1}</p>""").format( f.fileName(), f.errorString() ), ) return for index in range(first, -1, -1): data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) itm = self.__history[index] stream.writeUInt32(HISTORY_VERSION) stream.writeString(itm.url.encode("utf-8")) stream << itm.dateTime stream.writeString(itm.title.encode("utf-8")) f.write(data) f.close() if saveAll: if historyFile.exists() and not historyFile.remove(): E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Error removing old history file <b>{0}</b>.""" """<br/>Reason: {1}</p>""").format( historyFile.fileName(), historyFile.errorString() ), ) if not f.copy(historyFile.fileName()): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error moving new history file over old one """ """(<b>{0}</b>).<br/>Reason: {1}</p>""" ).format(historyFile.fileName(), f.errorString()), ) self.historySaved.emit() try: self.__lastSavedUrl = self.__history[0].url except IndexError: self.__lastSavedUrl = ""
def save(self): """ Public slot to save the history entries to disk. """ historyFile = QFile(self.getFileName()) if not historyFile.exists(): self.__lastSavedUrl = "" saveAll = self.__lastSavedUrl == "" first = len(self.__history) - 1 if not saveAll: # find the first one to save for index in range(len(self.__history)): if self.__history[index].url == self.__lastSavedUrl: first = index - 1 break if first == len(self.__history) - 1: saveAll = True if saveAll: # use a temporary file when saving everything f = QTemporaryFile() f.setAutoRemove(False) opened = f.open() else: f = historyFile opened = f.open(QIODevice.Append) if not opened: E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Unable to open history file <b>{0}</b>.<br/>""" """Reason: {1}</p>""").format(f.fileName(), f.errorString())) return for index in range(first, -1, -1): data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) itm = self.__history[index] stream.writeUInt32(HISTORY_VERSION) stream.writeString(itm.url.encode("utf-8")) stream << itm.dateTime stream.writeString(itm.title.encode('utf-8')) f.write(data) f.close() if saveAll: if historyFile.exists() and not historyFile.remove(): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error removing old history file <b>{0}</b>.""" """<br/>Reason: {1}</p>""").format( historyFile.fileName(), historyFile.errorString())) if not f.copy(historyFile.fileName()): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error moving new history file over old one """ """(<b>{0}</b>).<br/>Reason: {1}</p>""").format( historyFile.fileName(), f.errorString())) self.historySaved.emit() try: self.__lastSavedUrl = self.__history[0].url except IndexError: self.__lastSavedUrl = ""
def print_(doc, filename=None, widget=None): """Prints the popplerqt5.Poppler.Document. The filename is used in the dialog and print job name. If the filename is not given, it defaults to a translation of "PDF Document". The widget is a widget to use as parent for the print dialog etc. """ # Decide how we will print. # on Windows and Mac OS X a print command must be specified, otherwise # we'll use raster printing s = QSettings() s.beginGroup("helper_applications") cmd = s.value("printcommand", "", str) use_dialog = s.value("printcommand/dialog", False, bool) resolution = s.value("printcommand/dpi", 300, int) linux_lpr = False if os.name != 'nt' and not sys.platform.startswith('darwin'): # we're probably on Linux if not cmd: cmd = fileprinter.lprCommand() if cmd: linux_lpr = True elif cmd.split('/')[-1] in fileprinter.lpr_commands: linux_lpr = True print_file = filename title = os.path.basename(filename) if filename else _("PDF Document") if widget: try: printer = _printers[widget] except KeyError: printer = _printers[widget] = QPrinter() else: printer.setCopyCount(1) else: printer = QPrinter() printer.setDocName(title) printer.setPrintRange(QPrinter.AllPages) if linux_lpr or use_dialog or not cmd: dlg = QPrintDialog(printer, widget) dlg.setMinMax(1, doc.numPages()) dlg.setOption(QPrintDialog.PrintToFile, False) dlg.setWindowTitle( app.caption(_("Print {filename}").format(filename=title))) result = dlg.exec_() if widget: dlg.deleteLater() # because it has a parent if not result: return # cancelled if linux_lpr or '$ps' in cmd: # make a PostScript file with the desired paper size ps = QTemporaryFile() if ps.open() and qpopplerview.printer.psfile(doc, printer, ps): ps.close() print_file = ps.fileName() elif cmd: if printer.printRange() != QPrinter.AllPages: cmd = None # we can't cut out pages from a PDF file elif '$pdf' not in cmd: cmd += ' $pdf' command = [] if linux_lpr: # let all converted pages print printer.setPrintRange(QPrinter.AllPages) command = fileprinter.printCommand(cmd, printer, ps.fileName()) elif cmd and print_file: for arg in helpers.shell_split(cmd): if arg in ('$ps', '$pdf'): command.append(print_file) else: arg = arg.replace('$printer', printer.printerName()) command.append(arg) if command: if subprocess.call(command): QMessageBox.warning( widget, _("Printing Error"), _("Could not send the document to the printer.")) return else: # Fall back printing of rendered raster images. # It is unsure if the Poppler ArthurBackend ever will be ready for # good rendering directly to a painter, so we'll fall back to using # raster images. p = Printer() p.setDocument(doc) p.setPrinter(printer) p.setResolution(resolution) d = QProgressDialog() d.setModal(True) d.setMinimumDuration(0) d.setRange(0, len(p.pageList()) + 1) d.canceled.connect(p.abort) def progress(num, total, page): d.setValue(num) d.setLabelText( _("Printing page {page} ({num} of {total})...").format( page=page, num=num, total=total)) def finished(): p.deleteLater() d.deleteLater() d.hide() if not p.success and not p.aborted(): QMessageBox.warning( widget, _("Printing Error"), _("Could not send the document to the printer.")) p.finished.connect(finished) p.printing.connect(progress) p.start()
def print_(doc, filename=None, widget=None): """Prints the popplerqt5.Poppler.Document. The filename is used in the dialog and print job name. If the filename is not given, it defaults to a translation of "PDF Document". The widget is a widget to use as parent for the print dialog etc. """ # Decide how we will print. # on Windows and Mac OS X a print command must be specified, otherwise # we'll use raster printing s = QSettings() s.beginGroup("helper_applications") cmd = s.value("printcommand", "", str) use_dialog = s.value("printcommand/dialog", False, bool) resolution = s.value("printcommand/dpi", 300, int) linux_lpr = False if os.name != 'nt' and not sys.platform.startswith('darwin'): # we're probably on Linux if not cmd: cmd = fileprinter.lprCommand() if cmd: linux_lpr = True elif cmd.split('/')[-1] in fileprinter.lpr_commands: linux_lpr = True print_file = filename title = os.path.basename(filename) if filename else _("PDF Document") if widget: try: printer = _printers[widget] except KeyError: printer = _printers[widget] = QPrinter() else: printer.setCopyCount(1) else: printer = QPrinter() printer.setDocName(title) printer.setPrintRange(QPrinter.AllPages) if linux_lpr or use_dialog or not cmd: dlg = QPrintDialog(printer, widget) dlg.setMinMax(1, doc.numPages()) dlg.setOption(QPrintDialog.PrintToFile, False) dlg.setWindowTitle(app.caption(_("Print {filename}").format(filename=title))) result = dlg.exec_() if widget: dlg.deleteLater() # because it has a parent if not result: return # cancelled if linux_lpr or '$ps' in cmd: # make a PostScript file with the desired paper size ps = QTemporaryFile() if ps.open() and qpopplerview.printer.psfile(doc, printer, ps): ps.close() print_file = ps.fileName() elif cmd: if printer.printRange() != QPrinter.AllPages: cmd = None # we can't cut out pages from a PDF file elif '$pdf' not in cmd: cmd += ' $pdf' command = [] if linux_lpr: # let all converted pages print printer.setPrintRange(QPrinter.AllPages) command = fileprinter.printCommand(cmd, printer, ps.fileName()) elif cmd and print_file: for arg in helpers.shell_split(cmd): if arg in ('$ps', '$pdf'): command.append(print_file) else: arg = arg.replace('$printer', printer.printerName()) command.append(arg) if command: if subprocess.call(command): QMessageBox.warning(widget, _("Printing Error"), _("Could not send the document to the printer.")) return else: # Fall back printing of rendered raster images. # It is unsure if the Poppler ArthurBackend ever will be ready for # good rendering directly to a painter, so we'll fall back to using # raster images. p = Printer() p.setDocument(doc) p.setPrinter(printer) p.setResolution(resolution) d = QProgressDialog() d.setModal(True) d.setMinimumDuration(0) d.setRange(0, len(p.pageList()) + 1) d.canceled.connect(p.abort) def progress(num, total, page): d.setValue(num) d.setLabelText(_("Printing page {page} ({num} of {total})...").format( page=page, num=num, total=total)) def finished(): p.deleteLater() d.deleteLater() d.hide() if not p.success and not p.aborted(): QMessageBox.warning(widget, _("Printing Error"), _("Could not send the document to the printer.")) p.finished.connect(finished) p.printing.connect(progress) p.start()