class TextEdit(QMainWindow): def __init__(self, fileName=None, parent=None): super(TextEdit, self).__init__(parent) self.setToolButtonStyle(Qt.ToolButtonFollowStyle) self.setupFileActions() self.setupEditActions() self.setupTextActions() helpMenu = QMenu("Help", self) self.menuBar().addMenu(helpMenu) self.textEdit = QTextEdit(self) self.textEdit.currentCharFormatChanged.connect( self.currentCharFormatChanged) self.textEdit.cursorPositionChanged.connect(self.cursorPositionChanged) self.setCentralWidget(self.textEdit) self.textEdit.setFocus() self.setCurrentFileName() self.fontChanged(self.textEdit.font()) self.colorChanged(self.textEdit.textColor()) self.alignmentChanged(self.textEdit.alignment()) self.textEdit.document().modificationChanged.connect( self.actionSave.setEnabled) self.textEdit.document().modificationChanged.connect( self.setWindowModified) self.textEdit.document().undoAvailable.connect( self.actionUndo.setEnabled) self.textEdit.document().redoAvailable.connect( self.actionRedo.setEnabled) self.setWindowModified(self.textEdit.document().isModified()) self.actionSave.setEnabled(self.textEdit.document().isModified()) self.actionUndo.setEnabled(self.textEdit.document().isUndoAvailable()) self.actionRedo.setEnabled(self.textEdit.document().isRedoAvailable()) self.actionUndo.triggered.connect(self.textEdit.undo) self.actionRedo.triggered.connect(self.textEdit.redo) self.actionCut.setEnabled(False) self.actionCopy.setEnabled(False) self.actionCut.triggered.connect(self.textEdit.cut) self.actionCopy.triggered.connect(self.textEdit.copy) self.actionPaste.triggered.connect(self.textEdit.paste) self.textEdit.copyAvailable.connect(self.actionCut.setEnabled) self.textEdit.copyAvailable.connect(self.actionCopy.setEnabled) QApplication.clipboard().dataChanged.connect(self.clipboardDataChanged) # if fileName is None: # fileName = ':/example.html' if not self.load(fileName): self.fileNew() def closeEvent(self, e): if self.maybeSave(): e.accept() else: e.ignore() def setupFileActions(self): tb = QToolBar(self) tb.setWindowTitle("File Actions") self.addToolBar(tb) menu = QMenu("&File", self) self.menuBar().addMenu(menu) self.actionNew = QAction(QIcon.fromTheme( 'document-new', QIcon(rsrcPath + '/filenew.png')), "&New", self, priority=QAction.LowPriority, shortcut=QKeySequence.New, triggered=self.fileNew) tb.addAction(self.actionNew) menu.addAction(self.actionNew) self.actionOpen = QAction(QIcon.fromTheme( 'document-open', QIcon(rsrcPath + '/fileopen.png')), "&Open...", self, shortcut=QKeySequence.Open, triggered=self.fileOpen) tb.addAction(self.actionOpen) menu.addAction(self.actionOpen) menu.addSeparator() self.actionSave = QAction(QIcon.fromTheme( 'document-save', QIcon(rsrcPath + '/filesave.png')), "&Save", self, shortcut=QKeySequence.Save, triggered=self.fileSave, enabled=False) tb.addAction(self.actionSave) menu.addAction(self.actionSave) self.actionSaveAs = QAction("Save &As...", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.SHIFT + Qt.Key_S, triggered=self.fileSaveAs) menu.addAction(self.actionSaveAs) menu.addSeparator() self.actionPrint = QAction(QIcon.fromTheme( 'document-print', QIcon(rsrcPath + '/fileprint.png')), "&Print...", self, priority=QAction.LowPriority, shortcut=QKeySequence.Print, triggered=self.filePrint) tb.addAction(self.actionPrint) menu.addAction(self.actionPrint) self.actionPrintPreview = QAction( QIcon.fromTheme('fileprint', QIcon(rsrcPath + '/fileprint.png')), "Print Preview...", self, shortcut=Qt.CTRL + Qt.SHIFT + Qt.Key_P, triggered=self.filePrintPreview) menu.addAction(self.actionPrintPreview) self.actionPrintPdf = QAction(QIcon.fromTheme( 'exportpdf', QIcon(rsrcPath + '/exportpdf.png')), "&Export PDF...", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_D, triggered=self.filePrintPdf) tb.addAction(self.actionPrintPdf) menu.addAction(self.actionPrintPdf) menu.addSeparator() self.actionQuit = QAction("&Quit", self, shortcut=QKeySequence.Quit, triggered=self.close) menu.addAction(self.actionQuit) def setupEditActions(self): tb = QToolBar(self) tb.setWindowTitle("Edit Actions") self.addToolBar(tb) menu = QMenu("&Edit", self) self.menuBar().addMenu(menu) self.actionUndo = QAction(QIcon.fromTheme( 'edit-undo', QIcon(rsrcPath + '/editundo.png')), "&Undo", self, shortcut=QKeySequence.Undo) tb.addAction(self.actionUndo) menu.addAction(self.actionUndo) self.actionRedo = QAction(QIcon.fromTheme( 'edit-redo', QIcon(rsrcPath + '/editredo.png')), "&Redo", self, priority=QAction.LowPriority, shortcut=QKeySequence.Redo) tb.addAction(self.actionRedo) menu.addAction(self.actionRedo) menu.addSeparator() self.actionCut = QAction(QIcon.fromTheme( 'edit-cut', QIcon(rsrcPath + '/editcut.png')), "Cu&t", self, priority=QAction.LowPriority, shortcut=QKeySequence.Cut) tb.addAction(self.actionCut) menu.addAction(self.actionCut) self.actionCopy = QAction(QIcon.fromTheme( 'edit-copy', QIcon(rsrcPath + '/editcopy.png')), "&Copy", self, priority=QAction.LowPriority, shortcut=QKeySequence.Copy) tb.addAction(self.actionCopy) menu.addAction(self.actionCopy) self.actionPaste = QAction( QIcon.fromTheme('edit-paste', QIcon(rsrcPath + '/editpaste.png')), "&Paste", self, priority=QAction.LowPriority, shortcut=QKeySequence.Paste, enabled=(len(QApplication.clipboard().text()) != 0)) tb.addAction(self.actionPaste) menu.addAction(self.actionPaste) def setupTextActions(self): tb = QToolBar(self) tb.setWindowTitle("Format Actions") self.addToolBar(tb) menu = QMenu("F&ormat", self) self.menuBar().addMenu(menu) self.actionTextBold = QAction(QIcon.fromTheme( 'format-text-bold', QIcon(rsrcPath + '/textbold.png')), "&Bold", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_B, triggered=self.textBold, checkable=True) bold = QFont() bold.setBold(True) self.actionTextBold.setFont(bold) tb.addAction(self.actionTextBold) menu.addAction(self.actionTextBold) self.actionTextItalic = QAction(QIcon.fromTheme( 'format-text-italic', QIcon(rsrcPath + '/textitalic.png')), "&Italic", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_I, triggered=self.textItalic, checkable=True) italic = QFont() italic.setItalic(True) self.actionTextItalic.setFont(italic) tb.addAction(self.actionTextItalic) menu.addAction(self.actionTextItalic) self.actionTextUnderline = QAction(QIcon.fromTheme( 'format-text-underline', QIcon(rsrcPath + '/textunder.png')), "&Underline", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_U, triggered=self.textUnderline, checkable=True) underline = QFont() underline.setUnderline(True) self.actionTextUnderline.setFont(underline) tb.addAction(self.actionTextUnderline) menu.addAction(self.actionTextUnderline) menu.addSeparator() grp = QActionGroup(self, triggered=self.textAlign) # Make sure the alignLeft is always left of the alignRight. if QApplication.isLeftToRight(): self.actionAlignLeft = QAction( QIcon.fromTheme('format-justify-left', QIcon(rsrcPath + '/textleft.png')), "&Left", grp) self.actionAlignCenter = QAction( QIcon.fromTheme('format-justify-center', QIcon(rsrcPath + '/textcenter.png')), "C&enter", grp) self.actionAlignRight = QAction( QIcon.fromTheme('format-justify-right', QIcon(rsrcPath + '/textright.png')), "&Right", grp) else: self.actionAlignRight = QAction( QIcon.fromTheme('format-justify-right', QIcon(rsrcPath + '/textright.png')), "&Right", grp) self.actionAlignCenter = QAction( QIcon.fromTheme('format-justify-center', QIcon(rsrcPath + '/textcenter.png')), "C&enter", grp) self.actionAlignLeft = QAction( QIcon.fromTheme('format-justify-left', QIcon(rsrcPath + '/textleft.png')), "&Left", grp) self.actionAlignJustify = QAction( QIcon.fromTheme('format-justify-fill', QIcon(rsrcPath + '/textjustify.png')), "&Justify", grp) self.actionAlignLeft.setShortcut(Qt.CTRL + Qt.Key_L) self.actionAlignLeft.setCheckable(True) self.actionAlignLeft.setPriority(QAction.LowPriority) self.actionAlignCenter.setShortcut(Qt.CTRL + Qt.Key_E) self.actionAlignCenter.setCheckable(True) self.actionAlignCenter.setPriority(QAction.LowPriority) self.actionAlignRight.setShortcut(Qt.CTRL + Qt.Key_R) self.actionAlignRight.setCheckable(True) self.actionAlignRight.setPriority(QAction.LowPriority) self.actionAlignJustify.setShortcut(Qt.CTRL + Qt.Key_J) self.actionAlignJustify.setCheckable(True) self.actionAlignJustify.setPriority(QAction.LowPriority) tb.addActions(grp.actions()) menu.addActions(grp.actions()) menu.addSeparator() pix = QPixmap(16, 16) pix.fill(Qt.black) self.actionTextColor = QAction(QIcon(pix), "&Color...", self, triggered=self.textColor) tb.addAction(self.actionTextColor) menu.addAction(self.actionTextColor) tb = QToolBar(self) tb.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea) tb.setWindowTitle("Format Actions") self.addToolBarBreak(Qt.TopToolBarArea) self.addToolBar(tb) comboStyle = QComboBox(tb) tb.addWidget(comboStyle) comboStyle.addItem("Standard") comboStyle.addItem("Bullet List (Disc)") comboStyle.addItem("Bullet List (Circle)") comboStyle.addItem("Bullet List (Square)") comboStyle.addItem("Ordered List (Decimal)") comboStyle.addItem("Ordered List (Alpha lower)") comboStyle.addItem("Ordered List (Alpha upper)") comboStyle.addItem("Ordered List (Roman lower)") comboStyle.addItem("Ordered List (Roman upper)") comboStyle.activated.connect(self.textStyle) self.comboFont = QFontComboBox(tb) tb.addWidget(self.comboFont) self.comboFont.activated[str].connect(self.textFamily) self.comboSize = QComboBox(tb) self.comboSize.setObjectName("comboSize") tb.addWidget(self.comboSize) self.comboSize.setEditable(True) db = QFontDatabase() for size in db.standardSizes(): self.comboSize.addItem("%s" % (size)) self.comboSize.activated[str].connect(self.textSize) self.comboSize.setCurrentIndex( self.comboSize.findText("%s" % (QApplication.font().pointSize()))) def load(self, f): if not QFile.exists(f): return False fh = QFile(f) if not fh.open(QFile.ReadOnly): return False data = fh.readAll() codec = QTextCodec.codecForHtml(data) unistr = codec.toUnicode(data) if Qt.mightBeRichText(unistr): self.textEdit.setHtml(unistr) else: self.textEdit.setPlainText(unistr) self.setCurrentFileName(f) return True def maybeSave(self): if not self.textEdit.document().isModified(): return True if self.fileName.startswith(':/'): return True ret = QMessageBox.warning( self, "Application", "The document has been modified.\n" "Do you want to save your changes?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: return self.fileSave() if ret == QMessageBox.Cancel: return False return True def setCurrentFileName(self, fileName=''): self.fileName = fileName self.textEdit.document().setModified(False) if not fileName: shownName = 'untitled.txt' else: shownName = QFileInfo(fileName).fileName() self.setWindowTitle(self.tr("%s[*] - %s" % (shownName, "Rich Text"))) self.setWindowModified(False) def fileNew(self): if self.maybeSave(): self.textEdit.clear() self.setCurrentFileName() def fileOpen(self): fn, _ = QFileDialog.getOpenFileName( self, "Open File...", None, "HTML-Files (*.htm *.html);;All Files (*)") if fn: self.load(fn) def fileSave(self): if not self.fileName: return self.fileSaveAs() writer = QTextDocumentWriter(self.fileName) success = writer.write(self.textEdit.document()) if success: self.textEdit.document().setModified(False) return success def fileSaveAs(self): fn, _ = QFileDialog.getSaveFileName( self, "Save as...", None, "ODF files (*.odt);;HTML-Files (*.htm *.html);;All Files (*)") if not fn: return False lfn = fn.lower() if not lfn.endswith(('.odt', '.htm', '.html')): # The default. fn += '.odt' self.setCurrentFileName(fn) return self.fileSave() def filePrint(self): printer = QPrinter(QPrinter.HighResolution) dlg = QPrintDialog(printer, self) if self.textEdit.textCursor().hasSelection(): dlg.addEnabledOption(QPrintDialog.PrintSelection) dlg.setWindowTitle("Print Document") if dlg.exec_() == QPrintDialog.Accepted: self.textEdit.print_(printer) del dlg def filePrintPreview(self): printer = QPrinter(QPrinter.HighResolution) preview = QPrintPreviewDialog(printer, self) preview.paintRequested.connect(self.printPreview) preview.exec_() def printPreview(self, printer): self.textEdit.print_(printer) def filePrintPdf(self): fn, _ = QFileDialog.getSaveFileName( self, "Export PDF", None, "PDF files (*.pdf);;All Files (*)") if fn: if QFileInfo(fn).suffix().isEmpty(): fn += '.pdf' printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(fn) self.textEdit.document().print_(printer) def textBold(self): fmt = QTextCharFormat() fmt.setFontWeight(self.actionTextBold.isChecked() and QFont.Bold or QFont.Normal) self.mergeFormatOnWordOrSelection(fmt) def textUnderline(self): fmt = QTextCharFormat() fmt.setFontUnderline(self.actionTextUnderline.isChecked()) self.mergeFormatOnWordOrSelection(fmt) def textItalic(self): fmt = QTextCharFormat() fmt.setFontItalic(self.actionTextItalic.isChecked()) self.mergeFormatOnWordOrSelection(fmt) def textFamily(self, family): fmt = QTextCharFormat() fmt.setFontFamily(family) self.mergeFormatOnWordOrSelection(fmt) def textSize(self, pointSize): pointSize = float(pointSize) if pointSize > 0: fmt = QTextCharFormat() fmt.setFontPointSize(pointSize) self.mergeFormatOnWordOrSelection(fmt) def textStyle(self, styleIndex): cursor = self.textEdit.textCursor() if styleIndex: styleDict = { 1: QTextListFormat.ListDisc, 2: QTextListFormat.ListCircle, 3: QTextListFormat.ListSquare, 4: QTextListFormat.ListDecimal, 5: QTextListFormat.ListLowerAlpha, 6: QTextListFormat.ListUpperAlpha, 7: QTextListFormat.ListLowerRoman, 8: QTextListFormat.ListUpperRoman, } style = styleDict.get(styleIndex, QTextListFormat.ListDisc) cursor.beginEditBlock() blockFmt = cursor.blockFormat() listFmt = QTextListFormat() if cursor.currentList(): listFmt = cursor.currentList().format() else: listFmt.setIndent(blockFmt.indent() + 1) blockFmt.setIndent(0) cursor.setBlockFormat(blockFmt) listFmt.setStyle(style) cursor.createList(listFmt) cursor.endEditBlock() else: bfmt = QTextBlockFormat() bfmt.setObjectIndex(-1) cursor.mergeBlockFormat(bfmt) def textColor(self): col = QColorDialog.getColor(self.textEdit.textColor(), self) if not col.isValid(): return fmt = QTextCharFormat() fmt.setForeground(col) self.mergeFormatOnWordOrSelection(fmt) self.colorChanged(col) def textAlign(self, action): if action == self.actionAlignLeft: self.textEdit.setAlignment(Qt.AlignLeft | Qt.AlignAbsolute) elif action == self.actionAlignCenter: self.textEdit.setAlignment(Qt.AlignHCenter) elif action == self.actionAlignRight: self.textEdit.setAlignment(Qt.AlignRight | Qt.AlignAbsolute) elif action == self.actionAlignJustify: self.textEdit.setAlignment(Qt.AlignJustify) def currentCharFormatChanged(self, format): self.fontChanged(format.font()) self.colorChanged(format.foreground().color()) def cursorPositionChanged(self): self.alignmentChanged(self.textEdit.alignment()) def clipboardDataChanged(self): self.actionPaste.setEnabled(len(QApplication.clipboard().text()) != 0) def mergeFormatOnWordOrSelection(self, format): cursor = self.textEdit.textCursor() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) cursor.mergeCharFormat(format) self.textEdit.mergeCurrentCharFormat(format) def fontChanged(self, font): self.comboFont.setCurrentIndex( self.comboFont.findText(QFontInfo(font).family())) self.comboSize.setCurrentIndex( self.comboSize.findText("%s" % font.pointSize())) self.actionTextBold.setChecked(font.bold()) self.actionTextItalic.setChecked(font.italic()) self.actionTextUnderline.setChecked(font.underline()) def colorChanged(self, color): pix = QPixmap(16, 16) pix.fill(color) self.actionTextColor.setIcon(QIcon(pix)) def alignmentChanged(self, alignment): if alignment & Qt.AlignLeft: self.actionAlignLeft.setChecked(True) elif alignment & Qt.AlignHCenter: self.actionAlignCenter.setChecked(True) elif alignment & Qt.AlignRight: self.actionAlignRight.setChecked(True) elif alignment & Qt.AlignJustify: self.actionAlignJustify.setChecked(True)
class TextEdit(QMainWindow): def __init__(self, fileName=None, parent=None): super(TextEdit, self).__init__(parent) self.setWindowIcon(QIcon(':/images/logo.png')) self.setToolButtonStyle(Qt.ToolButtonFollowStyle) self.setupFileActions() self.setupEditActions() self.setupTextActions() helpMenu = QMenu("Help", self) self.menuBar().addMenu(helpMenu) helpMenu.addAction("About", self.about) helpMenu.addAction("About &Qt", QApplication.instance().aboutQt) self.textEdit = QTextEdit(self) self.textEdit.currentCharFormatChanged.connect( self.currentCharFormatChanged) self.textEdit.cursorPositionChanged.connect(self.cursorPositionChanged) self.setCentralWidget(self.textEdit) self.textEdit.setFocus() self.setCurrentFileName() self.fontChanged(self.textEdit.font()) self.colorChanged(self.textEdit.textColor()) self.alignmentChanged(self.textEdit.alignment()) self.textEdit.document().modificationChanged.connect( self.actionSave.setEnabled) self.textEdit.document().modificationChanged.connect( self.setWindowModified) self.textEdit.document().undoAvailable.connect( self.actionUndo.setEnabled) self.textEdit.document().redoAvailable.connect( self.actionRedo.setEnabled) self.setWindowModified(self.textEdit.document().isModified()) self.actionSave.setEnabled(self.textEdit.document().isModified()) self.actionUndo.setEnabled(self.textEdit.document().isUndoAvailable()) self.actionRedo.setEnabled(self.textEdit.document().isRedoAvailable()) self.actionUndo.triggered.connect(self.textEdit.undo) self.actionRedo.triggered.connect(self.textEdit.redo) self.actionCut.setEnabled(False) self.actionCopy.setEnabled(False) self.actionCut.triggered.connect(self.textEdit.cut) self.actionCopy.triggered.connect(self.textEdit.copy) self.actionPaste.triggered.connect(self.textEdit.paste) self.textEdit.copyAvailable.connect(self.actionCut.setEnabled) self.textEdit.copyAvailable.connect(self.actionCopy.setEnabled) QApplication.clipboard().dataChanged.connect(self.clipboardDataChanged) if fileName is None: fileName = ':/example.html' if not self.load(fileName): self.fileNew() def closeEvent(self, e): if self.maybeSave(): e.accept() else: e.ignore() def setupFileActions(self): tb = QToolBar(self) tb.setWindowTitle("File Actions") self.addToolBar(tb) menu = QMenu("&File", self) self.menuBar().addMenu(menu) self.actionNew = QAction( QIcon.fromTheme('document-new', QIcon(rsrcPath + '/filenew.png')), "&New", self, priority=QAction.LowPriority, shortcut=QKeySequence.New, triggered=self.fileNew) tb.addAction(self.actionNew) menu.addAction(self.actionNew) self.actionOpen = QAction( QIcon.fromTheme('document-open', QIcon(rsrcPath + '/fileopen.png')), "&Open...", self, shortcut=QKeySequence.Open, triggered=self.fileOpen) tb.addAction(self.actionOpen) menu.addAction(self.actionOpen) menu.addSeparator() self.actionSave = QAction( QIcon.fromTheme('document-save', QIcon(rsrcPath + '/filesave.png')), "&Save", self, shortcut=QKeySequence.Save, triggered=self.fileSave, enabled=False) tb.addAction(self.actionSave) menu.addAction(self.actionSave) self.actionSaveAs = QAction("Save &As...", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.SHIFT + Qt.Key_S, triggered=self.fileSaveAs) menu.addAction(self.actionSaveAs) menu.addSeparator() self.actionPrint = QAction( QIcon.fromTheme('document-print', QIcon(rsrcPath + '/fileprint.png')), "&Print...", self, priority=QAction.LowPriority, shortcut=QKeySequence.Print, triggered=self.filePrint) tb.addAction(self.actionPrint) menu.addAction(self.actionPrint) self.actionPrintPreview = QAction( QIcon.fromTheme('fileprint', QIcon(rsrcPath + '/fileprint.png')), "Print Preview...", self, shortcut=Qt.CTRL + Qt.SHIFT + Qt.Key_P, triggered=self.filePrintPreview) menu.addAction(self.actionPrintPreview) self.actionPrintPdf = QAction( QIcon.fromTheme('exportpdf', QIcon(rsrcPath + '/exportpdf.png')), "&Export PDF...", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_D, triggered=self.filePrintPdf) tb.addAction(self.actionPrintPdf) menu.addAction(self.actionPrintPdf) menu.addSeparator() self.actionQuit = QAction("&Quit", self, shortcut=QKeySequence.Quit, triggered=self.close) menu.addAction(self.actionQuit) def setupEditActions(self): tb = QToolBar(self) tb.setWindowTitle("Edit Actions") self.addToolBar(tb) menu = QMenu("&Edit", self) self.menuBar().addMenu(menu) self.actionUndo = QAction( QIcon.fromTheme('edit-undo', QIcon(rsrcPath + '/editundo.png')), "&Undo", self, shortcut=QKeySequence.Undo) tb.addAction(self.actionUndo) menu.addAction(self.actionUndo) self.actionRedo = QAction( QIcon.fromTheme('edit-redo', QIcon(rsrcPath + '/editredo.png')), "&Redo", self, priority=QAction.LowPriority, shortcut=QKeySequence.Redo) tb.addAction(self.actionRedo) menu.addAction(self.actionRedo) menu.addSeparator() self.actionCut = QAction( QIcon.fromTheme('edit-cut', QIcon(rsrcPath + '/editcut.png')), "Cu&t", self, priority=QAction.LowPriority, shortcut=QKeySequence.Cut) tb.addAction(self.actionCut) menu.addAction(self.actionCut) self.actionCopy = QAction( QIcon.fromTheme('edit-copy', QIcon(rsrcPath + '/editcopy.png')), "&Copy", self, priority=QAction.LowPriority, shortcut=QKeySequence.Copy) tb.addAction(self.actionCopy) menu.addAction(self.actionCopy) self.actionPaste = QAction( QIcon.fromTheme('edit-paste', QIcon(rsrcPath + '/editpaste.png')), "&Paste", self, priority=QAction.LowPriority, shortcut=QKeySequence.Paste, enabled=(len(QApplication.clipboard().text()) != 0)) tb.addAction(self.actionPaste) menu.addAction(self.actionPaste) def setupTextActions(self): tb = QToolBar(self) tb.setWindowTitle("Format Actions") self.addToolBar(tb) menu = QMenu("F&ormat", self) self.menuBar().addMenu(menu) self.actionTextBold = QAction( QIcon.fromTheme('format-text-bold', QIcon(rsrcPath + '/textbold.png')), "&Bold", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_B, triggered=self.textBold, checkable=True) bold = QFont() bold.setBold(True) self.actionTextBold.setFont(bold) tb.addAction(self.actionTextBold) menu.addAction(self.actionTextBold) self.actionTextItalic = QAction( QIcon.fromTheme('format-text-italic', QIcon(rsrcPath + '/textitalic.png')), "&Italic", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_I, triggered=self.textItalic, checkable=True) italic = QFont() italic.setItalic(True) self.actionTextItalic.setFont(italic) tb.addAction(self.actionTextItalic) menu.addAction(self.actionTextItalic) self.actionTextUnderline = QAction( QIcon.fromTheme('format-text-underline', QIcon(rsrcPath + '/textunder.png')), "&Underline", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.Key_U, triggered=self.textUnderline, checkable=True) underline = QFont() underline.setUnderline(True) self.actionTextUnderline.setFont(underline) tb.addAction(self.actionTextUnderline) menu.addAction(self.actionTextUnderline) menu.addSeparator() grp = QActionGroup(self, triggered=self.textAlign) # Make sure the alignLeft is always left of the alignRight. if QApplication.isLeftToRight(): self.actionAlignLeft = QAction( QIcon.fromTheme('format-justify-left', QIcon(rsrcPath + '/textleft.png')), "&Left", grp) self.actionAlignCenter = QAction( QIcon.fromTheme('format-justify-center', QIcon(rsrcPath + '/textcenter.png')), "C&enter", grp) self.actionAlignRight = QAction( QIcon.fromTheme('format-justify-right', QIcon(rsrcPath + '/textright.png')), "&Right", grp) else: self.actionAlignRight = QAction( QIcon.fromTheme('format-justify-right', QIcon(rsrcPath + '/textright.png')), "&Right", grp) self.actionAlignCenter = QAction( QIcon.fromTheme('format-justify-center', QIcon(rsrcPath + '/textcenter.png')), "C&enter", grp) self.actionAlignLeft = QAction( QIcon.fromTheme('format-justify-left', QIcon(rsrcPath + '/textleft.png')), "&Left", grp) self.actionAlignJustify = QAction( QIcon.fromTheme('format-justify-fill', QIcon(rsrcPath + '/textjustify.png')), "&Justify", grp) self.actionAlignLeft.setShortcut(Qt.CTRL + Qt.Key_L) self.actionAlignLeft.setCheckable(True) self.actionAlignLeft.setPriority(QAction.LowPriority) self.actionAlignCenter.setShortcut(Qt.CTRL + Qt.Key_E) self.actionAlignCenter.setCheckable(True) self.actionAlignCenter.setPriority(QAction.LowPriority) self.actionAlignRight.setShortcut(Qt.CTRL + Qt.Key_R) self.actionAlignRight.setCheckable(True) self.actionAlignRight.setPriority(QAction.LowPriority) self.actionAlignJustify.setShortcut(Qt.CTRL + Qt.Key_J) self.actionAlignJustify.setCheckable(True) self.actionAlignJustify.setPriority(QAction.LowPriority) tb.addActions(grp.actions()) menu.addActions(grp.actions()) menu.addSeparator() pix = QPixmap(16, 16) pix.fill(Qt.black) self.actionTextColor = QAction(QIcon(pix), "&Color...", self, triggered=self.textColor) tb.addAction(self.actionTextColor) menu.addAction(self.actionTextColor) tb = QToolBar(self) tb.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea) tb.setWindowTitle("Format Actions") self.addToolBarBreak(Qt.TopToolBarArea) self.addToolBar(tb) comboStyle = QComboBox(tb) tb.addWidget(comboStyle) comboStyle.addItem("Standard") comboStyle.addItem("Bullet List (Disc)") comboStyle.addItem("Bullet List (Circle)") comboStyle.addItem("Bullet List (Square)") comboStyle.addItem("Ordered List (Decimal)") comboStyle.addItem("Ordered List (Alpha lower)") comboStyle.addItem("Ordered List (Alpha upper)") comboStyle.addItem("Ordered List (Roman lower)") comboStyle.addItem("Ordered List (Roman upper)") comboStyle.activated.connect(self.textStyle) self.comboFont = QFontComboBox(tb) tb.addWidget(self.comboFont) self.comboFont.activated[str].connect(self.textFamily) self.comboSize = QComboBox(tb) self.comboSize.setObjectName("comboSize") tb.addWidget(self.comboSize) self.comboSize.setEditable(True) db = QFontDatabase() for size in db.standardSizes(): self.comboSize.addItem("%s" % (size)) self.comboSize.activated[str].connect(self.textSize) self.comboSize.setCurrentIndex( self.comboSize.findText( "%s" % (QApplication.font().pointSize()))) def load(self, f): if not QFile.exists(f): return False fh = QFile(f) if not fh.open(QFile.ReadOnly): return False data = fh.readAll() codec = QTextCodec.codecForHtml(data) unistr = codec.toUnicode(data) if Qt.mightBeRichText(unistr): self.textEdit.setHtml(unistr) else: self.textEdit.setPlainText(unistr) self.setCurrentFileName(f) return True def maybeSave(self): if not self.textEdit.document().isModified(): return True if self.fileName.startswith(':/'): return True ret = QMessageBox.warning(self, "Application", "The document has been modified.\n" "Do you want to save your changes?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: return self.fileSave() if ret == QMessageBox.Cancel: return False return True def setCurrentFileName(self, fileName=''): self.fileName = fileName self.textEdit.document().setModified(False) if not fileName: shownName = 'untitled.txt' else: shownName = QFileInfo(fileName).fileName() self.setWindowTitle(self.tr("%s[*] - %s" % (shownName, "Rich Text"))) self.setWindowModified(False) def fileNew(self): if self.maybeSave(): self.textEdit.clear() self.setCurrentFileName() def fileOpen(self): fn, _ = QFileDialog.getOpenFileName(self, "Open File...", None, "HTML-Files (*.htm *.html);;All Files (*)") if fn: self.load(fn) def fileSave(self): if not self.fileName: return self.fileSaveAs() writer = QTextDocumentWriter(self.fileName) success = writer.write(self.textEdit.document()) if success: self.textEdit.document().setModified(False) return success def fileSaveAs(self): fn, _ = QFileDialog.getSaveFileName(self, "Save as...", None, "ODF files (*.odt);;HTML-Files (*.htm *.html);;All Files (*)") if not fn: return False lfn = fn.lower() if not lfn.endswith(('.odt', '.htm', '.html')): # The default. fn += '.odt' self.setCurrentFileName(fn) return self.fileSave() def filePrint(self): printer = QPrinter(QPrinter.HighResolution) dlg = QPrintDialog(printer, self) if self.textEdit.textCursor().hasSelection(): dlg.addEnabledOption(QPrintDialog.PrintSelection) dlg.setWindowTitle("Print Document") if dlg.exec_() == QPrintDialog.Accepted: self.textEdit.print_(printer) del dlg def filePrintPreview(self): printer = QPrinter(QPrinter.HighResolution) preview = QPrintPreviewDialog(printer, self) preview.paintRequested.connect(self.printPreview) preview.exec_() def printPreview(self, printer): self.textEdit.print_(printer) def filePrintPdf(self): fn, _ = QFileDialog.getSaveFileName(self, "Export PDF", None, "PDF files (*.pdf);;All Files (*)") if fn: if QFileInfo(fn).suffix().isEmpty(): fn += '.pdf' printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(fn) self.textEdit.document().print_(printer) def textBold(self): fmt = QTextCharFormat() fmt.setFontWeight(self.actionTextBold.isChecked() and QFont.Bold or QFont.Normal) self.mergeFormatOnWordOrSelection(fmt) def textUnderline(self): fmt = QTextCharFormat() fmt.setFontUnderline(self.actionTextUnderline.isChecked()) self.mergeFormatOnWordOrSelection(fmt) def textItalic(self): fmt = QTextCharFormat() fmt.setFontItalic(self.actionTextItalic.isChecked()) self.mergeFormatOnWordOrSelection(fmt) def textFamily(self, family): fmt = QTextCharFormat() fmt.setFontFamily(family) self.mergeFormatOnWordOrSelection(fmt) def textSize(self, pointSize): pointSize = float(pointSize) if pointSize > 0: fmt = QTextCharFormat() fmt.setFontPointSize(pointSize) self.mergeFormatOnWordOrSelection(fmt) def textStyle(self, styleIndex): cursor = self.textEdit.textCursor() if styleIndex: styleDict = { 1: QTextListFormat.ListDisc, 2: QTextListFormat.ListCircle, 3: QTextListFormat.ListSquare, 4: QTextListFormat.ListDecimal, 5: QTextListFormat.ListLowerAlpha, 6: QTextListFormat.ListUpperAlpha, 7: QTextListFormat.ListLowerRoman, 8: QTextListFormat.ListUpperRoman, } style = styleDict.get(styleIndex, QTextListFormat.ListDisc) cursor.beginEditBlock() blockFmt = cursor.blockFormat() listFmt = QTextListFormat() if cursor.currentList(): listFmt = cursor.currentList().format() else: listFmt.setIndent(blockFmt.indent() + 1) blockFmt.setIndent(0) cursor.setBlockFormat(blockFmt) listFmt.setStyle(style) cursor.createList(listFmt) cursor.endEditBlock() else: bfmt = QTextBlockFormat() bfmt.setObjectIndex(-1) cursor.mergeBlockFormat(bfmt) def textColor(self): col = QColorDialog.getColor(self.textEdit.textColor(), self) if not col.isValid(): return fmt = QTextCharFormat() fmt.setForeground(col) self.mergeFormatOnWordOrSelection(fmt) self.colorChanged(col) def textAlign(self, action): if action == self.actionAlignLeft: self.textEdit.setAlignment(Qt.AlignLeft | Qt.AlignAbsolute) elif action == self.actionAlignCenter: self.textEdit.setAlignment(Qt.AlignHCenter) elif action == self.actionAlignRight: self.textEdit.setAlignment(Qt.AlignRight | Qt.AlignAbsolute) elif action == self.actionAlignJustify: self.textEdit.setAlignment(Qt.AlignJustify) def currentCharFormatChanged(self, format): self.fontChanged(format.font()) self.colorChanged(format.foreground().color()) def cursorPositionChanged(self): self.alignmentChanged(self.textEdit.alignment()) def clipboardDataChanged(self): self.actionPaste.setEnabled(len(QApplication.clipboard().text()) != 0) def about(self): QMessageBox.about(self, "About", "This example demonstrates Qt's rich text editing facilities " "in action, providing an example document for you to " "experiment with.") def mergeFormatOnWordOrSelection(self, format): cursor = self.textEdit.textCursor() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) cursor.mergeCharFormat(format) self.textEdit.mergeCurrentCharFormat(format) def fontChanged(self, font): self.comboFont.setCurrentIndex( self.comboFont.findText(QFontInfo(font).family())) self.comboSize.setCurrentIndex( self.comboSize.findText("%s" % font.pointSize())) self.actionTextBold.setChecked(font.bold()) self.actionTextItalic.setChecked(font.italic()) self.actionTextUnderline.setChecked(font.underline()) def colorChanged(self, color): pix = QPixmap(16, 16) pix.fill(color) self.actionTextColor.setIcon(QIcon(pix)) def alignmentChanged(self, alignment): if alignment & Qt.AlignLeft: self.actionAlignLeft.setChecked(True) elif alignment & Qt.AlignHCenter: self.actionAlignCenter.setChecked(True) elif alignment & Qt.AlignRight: self.actionAlignRight.setChecked(True) elif alignment & Qt.AlignJustify: self.actionAlignJustify.setChecked(True)
class ReportEditor(QMainWindow, Ui_ReportEditorWindow): def __init__(self, processor, parent=None): super().__init__(parent) self.processor = processor self.settings = SupremeSettings() self._report_items = {} self._file_name = None self.setupUi(self) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 3) self.actionUpdate.triggered.connect(self._create_report) self.usedList.doubleClicked.connect( lambda i: self.usedList.takeItem(i.row())) self._setup_text_editor() self._setup_text_connections() self._init_report_items() def _init_report_items(self): items = [report_class(self.processor, parent=self.availableList) for report_class in _report_classes] factory = AlgorithmReportFactory(self.processor, self.availableList) items += factory.get_report_items() self._report_items = {} for report_item in items: self._report_items[report_item.name] = report_item self.availableList.addItem(report_item) self.availableList.mousePressEvent = self._av_list_mouse_press_event def _av_list_mouse_press_event(self, event: QMouseEvent): if event.button() == Qt.RightButton: item = self.availableList.itemAt(event.pos()) if hasattr(item, 'settings'): item.change_settings() QListWidget.mousePressEvent(self.availableList, event) def _create_report(self): self.textEdit.clear() self.statusbar.showMessage('Создание отчёта...') html = "" for i in range(self.usedList.count()): list_item = self.usedList.item(i) report_item = self._report_items[list_item.text()] html += report_item.create_html() html = encapsulate_html(html) self.textEdit.setHtml(html) self.textEdit.document().setModified(True) self.statusbar.showMessage('Отчёт создан') def _setup_text_editor(self): self.styleComboBox = QComboBox(self.fontToolBar) self.styleComboBox.addItem("Standard") self.styleComboBox.addItem("Bullet List (Disc)") self.styleComboBox.addItem("Bullet List (Circle)") self.styleComboBox.addItem("Bullet List (Square)") self.styleComboBox.addItem("Ordered List (Decimal)") self.styleComboBox.addItem("Ordered List (Alpha lower)") self.styleComboBox.addItem("Ordered List (Alpha upper)") self.styleComboBox.addItem("Ordered List (Roman lower)") self.styleComboBox.addItem("Ordered List (Roman upper)") self.styleComboBox.addItem("Heading 1") self.styleComboBox.addItem("Heading 2") self.styleComboBox.addItem("Heading 3") self.styleComboBox.addItem("Heading 4") self.styleComboBox.addItem("Heading 5") self.styleComboBox.addItem("Heading 6") self.fontToolBar.addWidget(self.styleComboBox) self.fontComboBox = QFontComboBox(self.fontToolBar) # TODO connect self.fontToolBar.addWidget(self.fontComboBox) self.sizeComboBox = QComboBox(self.fontToolBar) # TODO connect sizes = QFontDatabase.standardSizes() [self.sizeComboBox.addItem(str(size)) for size in sizes] self.sizeComboBox.setCurrentIndex( sizes.index(QApplication.font().pointSize())) self.fontToolBar.addWidget(self.sizeComboBox) def _setup_text_connections(self): self.textEdit.currentCharFormatChanged.connect( self._current_char_format_changed) self.textEdit.cursorPositionChanged.connect( self._cursor_position_changed) self.actionSave.triggered.connect(self._save) self.actionSaveAs.triggered.connect(self._save_as) self.actionBrowser.triggered.connect(self._browser) self.actionPrint.triggered.connect(self._print) self.actionPrintPreview.triggered.connect(self._print_preview) self.actionPDF.triggered.connect(self._print_pdf) self.textEdit.document().modificationChanged.connect( self.actionSave.setEnabled) self.textEdit.document().modificationChanged.connect( self.actionSaveAs.setEnabled) self.styleComboBox.activated.connect(self._text_style) self.fontComboBox.currentTextChanged.connect(self._text_family) self.sizeComboBox.currentTextChanged.connect(self._text_size) self.actionTextBold.triggered.connect(self._text_bold) self.actionTextItalic.triggered.connect(self._text_italic) self.actionTextUnderline.triggered.connect(self._text_underline) self.actionTextColor.triggered.connect(self._text_color) self.actionTextLeft.triggered.connect(self._text_align) self.actionTextRight.triggered.connect(self._text_align) self.actionTextCenter.triggered.connect(self._text_align) self.actionTextJustify.triggered.connect(self._text_align) self.actionUndo.triggered.connect(self.textEdit.undo) self.actionRedo.triggered.connect(self.textEdit.redo) self._font_changed(self.textEdit.font()) self._color_changed(self.textEdit.textColor()) self._alignment_changed(self.textEdit.alignment()) self.actionSave.setEnabled(self.textEdit.document().isModified()) self.actionUndo.setEnabled(self.textEdit.document().isUndoAvailable()) self.actionRedo.setEnabled(self.textEdit.document().isRedoAvailable()) QApplication.clipboard().dataChanged.connect( self._clipboard_data_changed) def _save(self): if not self._file_name: return self._save_as() if self._file_name.startswith(':/'): return self._save_as() writer = QTextDocumentWriter(self._file_name) success = writer.write(self.textEdit.document()) if success: self.statusbar.showMessage('Сохранено успешно') else: self.statusbar.showMessage('Ошибка сохранения') def _save_as(self): dialog = QFileDialog(self, 'Сохранить как...') dialog.setAcceptMode(QFileDialog.AcceptSave) mime_types = ["text/html", "text/plain", "application/vnd.oasis.opendocument.text"] dialog.setMimeTypeFilters(mime_types) dialog.setDefaultSuffix("html") if dialog.exec_() != QDialog.Accepted: self.statusbar.showMessage('Сохранение отменено') return False self._file_name = dialog.selectedFiles()[0] return self._save() def _print(self): printer = QPrinter(QPrinter.HighResolution) self.print_dialog = QPrintDialog(printer, self) if self.textEdit.textCursor().hasSelection(): self.print_dialog.addEnabledOption(QPrintDialog.PrintSelection) self.print_dialog.setWindowTitle('Печать') if self.print_dialog.exec_() == QDialog.accepted: self.textEdit.print(printer) self.print_dialog = None def _print_preview(self): printer = QPrinter(QPrinter.HighResolution) self.preview_dialog = QPrintPreviewDialog(printer, self) self.preview_dialog.paintRequested.connect( self._actually_print_preview) self.preview_dialog.exec_() def _browser(self, not_open=False): filename = f'{self.settings["tempdir"]}/temp_report.html' writer = QTextDocumentWriter(filename) writer.write(self.textEdit.document()) if not not_open: webbrowser.open_new(filename) def _actually_print_preview(self, printer: QPrinter): self.textEdit.print(printer) def _print_pdf(self): dialog = QFileDialog(self, 'Сохранить в PDF') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setMimeTypeFilters(['application/pdf']) dialog.setDefaultSuffix('pdf') if dialog.exec_() != QDialog.Accepted: return name = dialog.selectedFiles()[0] self._browser(True) pdfkit.from_file(f'{self.settings["tempdir"]}/temp_report.html', name) self.statusbar.showMessage('Экспорт успешен') if platform.system() == 'Darwin': # macOS subprocess.call(('open', name)) elif platform.system() == 'Windows': # Windows os.startfile(name) else: # linux variants subprocess.call(('xdg-open', name)) def _text_bold(self): fmt = QTextCharFormat() fmt.setFontWeight(QFont.Bold if self.actionTextBold.isChecked() else QFont.Normal) self._merge_text_format(fmt) def _text_italic(self): fmt = QTextCharFormat() fmt.setFontItalic(self.actionTextItalic.isChecked()) self._merge_text_format(fmt) def _text_underline(self): fmt = QTextCharFormat() fmt.setFontUnderline(self.actionTextUnderline.isChecked()) self._merge_text_format(fmt) def _merge_text_format(self, format): cursor = self.textEdit.textCursor() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) cursor.mergeCharFormat(format) self.textEdit.mergeCurrentCharFormat(format) def _cursor_position_changed(self): self._alignment_changed(self.textEdit.alignment()) text_list = self.textEdit.textCursor().currentList() if text_list: list_formats = [ QTextListFormat.ListDisc, QTextListFormat.ListCircle, QTextListFormat.ListSquare, QTextListFormat.ListDecimal, QTextListFormat.ListLowerAlpha, QTextListFormat.ListUpperAlpha, QTextListFormat.ListLowerRoman, QTextListFormat.ListUpperRoman ] try: list_index = list_formats.index(text_list.format().style()) except ValueError: list_index = -1 self.styleComboBox.setCurrentIndex(list_index) else: heading_level = self.textEdit.textCursor().blockFormat() \ .headingLevel() self.styleComboBox.setCurrentIndex( heading_level + 8 if heading_level else 0) def _current_char_format_changed(self, format): self._font_changed(format.font()) self._color_changed(format.foreground().color()) def _text_style(self, index: int): styles = { 1: QTextListFormat.ListDisc, 2: QTextListFormat.ListCircle, 3: QTextListFormat.ListSquare, 4: QTextListFormat.ListDecimal, 5: QTextListFormat.ListLowerAlpha, 6: QTextListFormat.ListUpperAlpha, 7: QTextListFormat.ListLowerRoman, 8: QTextListFormat.ListUpperRoman } cursor = self.textEdit.textCursor() try: style = styles[index] except KeyError: style = None cursor.beginEditBlock() block_fmt = cursor.blockFormat() if style is None: block_fmt.setObjectIndex(-1) heading_level = index - 9 + 1 if index >= 9 else 0 block_fmt.setHeadingLevel(heading_level) cursor.setBlockFormat(block_fmt) size = 4 - heading_level if heading_level else 0 fmt = QTextCharFormat() fmt.setFontWeight(QFont.Bold if heading_level else QFont.Normal) fmt.setProperty(QTextFormat.FontSizeAdjustment, size) cursor.select(QTextCursor.LineUnderCursor) cursor.mergeCharFormat(fmt) self.textEdit.mergeCurrentCharFormat(fmt) else: list_fmt = QTextListFormat() if cursor.currentList(): list_fmt = cursor.currentList().format() else: list_fmt.setIndent(block_fmt.indent() + 1) block_fmt.setIndent(0) cursor.setBlockFormat(block_fmt) list_fmt.setStyle(style) cursor.createList(list_fmt) cursor.endEditBlock() def _text_family(self, font: str): fmt = QTextCharFormat() fmt.setFontFamily(font) self._merge_text_format(fmt) def _text_size(self, size: str): size = float(size) fmt = QTextCharFormat() fmt.setFontPointSize(size) self._merge_text_format(fmt) def _text_color(self): col = QColorDialog.getColor(self.textEdit.textColor(), self) if not col.isValid(): return fmt = QTextCharFormat() fmt.setForeground(col) self._merge_text_format(fmt) self._color_changed(col) def _text_align(self): action = self.sender() if action == self.actionTextLeft: self.textEdit.setAlignment(Qt.AlignLeft | Qt.AlignAbsolute) elif action == self.actionTextCenter: self.textEdit.setAlignment(Qt.AlignHCenter) elif action == self.actionTextRight: self.textEdit.setAlignment(Qt.AlignRight | Qt.AlignAbsolute) elif action == self.actionTextJustify: self.textEdit.setAlignment(Qt.AlignJustify) def _font_changed(self, font): self.fontComboBox.setCurrentIndex(self.fontComboBox.findText( QFontInfo(font).family())) self.sizeComboBox.setCurrentIndex(self.sizeComboBox.findText( str(int(font.pointSize())))) self.actionTextBold.setChecked(font.bold()) self.actionTextItalic.setChecked(font.italic()) self.actionTextUnderline.setChecked(font.underline()) def _color_changed(self, color): pass def _alignment_changed(self, alignment): [a.setChecked(False) for a in (self.actionTextLeft, self.actionTextRight, self.actionTextCenter, self.actionTextJustify)] if alignment & Qt.AlignLeft: self.actionTextLeft.setChecked(True) elif alignment & Qt.AlignHCenter: self.actionTextCenter.setChecked(True) elif alignment & Qt.AlignRight: self.actionTextRight.setChecked(True) elif alignment & Qt.AlignJustify: self.actionTextJustify.setChecked(True) def _clipboard_data_changed(self): md = QApplication.clipboard().mimeData() if md: self.actionTextPaste.setEnabled(md.hasText())
class project: projectName = "" paratextFolder = "" audioFolderName = "" textFont = "" textSize = 0 fileType = "" bBook = False currentBook = 1 currentChapter = 1 def project(self): pass def readProject(self, currentProject): try: print("Reading project " + currentProject) refMatcher = re.compile("^CurrentReference=([^ ]+) (\\d+)$") for line in open(currentProject + '.prj'): line = line.strip() mtch = refMatcher.match(line) if mtch: self.currentBook = mtch.group(1) # bk = mtch.group(1) # for i, b in enumerate(data.data.book): # if b.equals(bk): # self.currentBook = i # break self.currentChapter = mtch.group(2) elif line.startswith("ProjectName="): self.projectName = line[len("ProjectName="):] elif line.startswith("VersionName="): self.projectName = line[len("VersionName="):] elif line.startswith("ParatextFolder="): self.paratextFolder = line[len("ParatextFolder="):] elif line.startswith("SoundFolder="): self.audioFolderName = line[len("SoundFolder="):] elif line.startswith("AudioFolder="): self.audioFolderName = line[len("AudioFolder="):] elif line.startswith("Font="): self.textFont = line[len("Font="):] elif line.startswith("FontSize="): self.textSize = int(line[len("FontSize=")]) elif line.startswith("FileType="): self.fileType = line[len("FileType="):] self.bBook = self.fileType == "Book" else: print("Unknown project option: ", line) except FileNotFoundError: print("Failed to open project file") self.writeProject(currentProject) pass except Exception as detail: print("Exception reading project file: ", detail) pass def writeProject(self, currentProject): print("Writing project file") try: fh = open(currentProject + ".prj", "w+") fh.write("CurrentReference=" + self.currentBook + " " + str(self.currentChapter) + "\n") fh.write("ProjectName=" + self.projectName + "\n") fh.write("ParatextFolder=" + self.paratextFolder + "\n") fh.write("AudioFolder=" + self.audioFolderName + "\n") fh.write("Font=" + self.textFont + "\n") fh.write("FontSize=" + str(self.textSize) + "\n") fh.write("FileType=" + self.fileType + "\n") fh.close() except Exception as detail: print("IOException writing project file: ", detail) pass # class Ui_Dialog(object): def setupUi(self, Dialog, proj, newProject): try: self.dialog = Dialog self.proj = proj Dialog.setObjectName("Dialog") Dialog.resize(400, 357) self.buttonBox = QDialogButtonBox(Dialog) self.buttonBox.setGeometry(QRect(30, 310, 341, 32)) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.groupBox = QGroupBox(Dialog) self.groupBox.setGeometry(QRect(10, 0, 381, 61)) self.groupBox.setObjectName("groupBox") self.lineEditProjectName = QLineEdit(self.groupBox) self.lineEditProjectName.setGeometry(QRect(10, 30, 361, 23)) self.lineEditProjectName.setObjectName("lineEditProjectName") self.groupBox_2 = QGroupBox(Dialog) self.groupBox_2.setGeometry(QRect(10, 60, 381, 61)) self.groupBox_2.setObjectName("groupBox_2") self.comboBoxProjectType = QComboBox(self.groupBox_2) self.comboBoxProjectType.setGeometry(QRect(10, 30, 361, 23)) self.comboBoxProjectType.setObjectName("comboBoxProjectType") self.groupBox_3 = QGroupBox(Dialog) self.groupBox_3.setGeometry(QRect(10, 120, 381, 61)) self.groupBox_3.setObjectName("groupBox_3") self.lineEditSourcePath = QLineEdit(self.groupBox_3) self.lineEditSourcePath.setGeometry(QRect(10, 30, 271, 23)) self.lineEditSourcePath.setObjectName("lineEditSourcePath") self.pushButtonBrowseSource = QPushButton(self.groupBox_3) self.pushButtonBrowseSource.setGeometry(QRect(290, 30, 80, 23)) self.pushButtonBrowseSource.setObjectName("pushButtonBrowseSource") self.groupBox_4 = QGroupBox(Dialog) self.groupBox_4.setGeometry(QRect(10, 180, 381, 61)) self.groupBox_4.setObjectName("groupBox_4") self.pushButtonBrowseAudio = QPushButton(self.groupBox_4) self.pushButtonBrowseAudio.setGeometry(QRect(290, 30, 80, 23)) self.pushButtonBrowseAudio.setObjectName("pushButtonBrowseAudio") self.lineEditAudioFilesPath = QLineEdit(self.groupBox_4) self.lineEditAudioFilesPath.setGeometry(QRect(10, 30, 271, 23)) self.lineEditAudioFilesPath.setObjectName("lineEditAudioFilesPath") self.groupBox_5 = QGroupBox(Dialog) self.groupBox_5.setGeometry(QRect(10, 240, 381, 61)) self.groupBox_5.setObjectName("groupBox_5") self.comboBoxFont = QFontComboBox(self.groupBox_5) self.comboBoxFont.setGeometry(QRect(10, 30, 271, 23)) self.comboBoxFont.setObjectName("comboBoxFont") self.lineEditFontSize = QLineEdit(self.groupBox_5) self.lineEditFontSize.setGeometry(QRect(290, 30, 81, 23)) self.lineEditFontSize.setObjectName("lineEditFontSize") # set up fields if newProject: self.projectName = "" self.paratextFolder = "c:\\My Paratext 8 Projects" self.textFont = "Times New Roman" self.textSize = 25 self.fileType = "Paratext" typeList = ("Paratext", "Book", "BART") # self.comboBoxProjectType.clear() for index, i in enumerate(typeList): self.comboBoxProjectType.addItem(i) index = self.comboBoxProjectType.findText(self.fileType, Qt.MatchFixedString) if index >= 0: self.comboBoxProjectType.setCurrentIndex(index) self.lineEditProjectName.setText(self.projectName) self.lineEditSourcePath.setText(self.paratextFolder) self.lineEditAudioFilesPath.setText(self.audioFolderName) index = self.comboBoxFont.findText(self.textFont, Qt.MatchFixedString) if index >= 0: self.comboBoxFont.setCurrentIndex(index) self.lineEditFontSize.setText(str(self.textSize)) self.retranslateUi(Dialog) self.pushButtonBrowseSource.clicked.connect(self.browse_source) self.pushButtonBrowseAudio.clicked.connect(self.browse_audio_path) self.lineEditProjectName.textChanged.connect( self.lineEditProjectName_changed) self.comboBoxProjectType.currentTextChanged.connect( self.comboBoxProjectType_changed) self.comboBoxFont.currentTextChanged.connect( self.comboBoxFont_changed) self.lineEditFontSize.textChanged.connect( self.lineEditFontSize_changed) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) QMetaObject.connectSlotsByName(Dialog) except Exception as detail: print("Exception: " + detail) def retranslateUi(self, Dialog): _translate = QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.groupBox.setTitle(_translate("Dialog", "Project name")) self.groupBox_2.setTitle(_translate("Dialog", "Type")) self.groupBox_3.setTitle(_translate("Dialog", "Source")) self.pushButtonBrowseSource.setText(_translate("Dialog", "Browse...")) self.groupBox_4.setTitle(_translate("Dialog", "Audio files folder")) self.pushButtonBrowseAudio.setText(_translate("Dialog", "Browse...")) self.groupBox_5.setTitle(_translate("Dialog", "Font")) def accept(self): self.writeProject(self.projectName) print("Saved project " + self.projectName) self.dialog.close() def reject(self): print("Cancel") self.dialog.close() def comboBoxProjectType_changed(self): self.fileType = self.comboBoxProjectType.currentText() # print("Changing project type to " + self.fileType) self.bBook = True if self.fileType == "Paratext": self.paratextFolder = "c:\\Paratext\\My Paratext 8 Projects\\" + self.lineEditProjectName.text( ) self.bBook = False elif self.fileType == "Book": self.paratextFolder = "" else: self.paratextFolder = "" self.lineEditSourcePath.setText(self.paratextFolder) def lineEditProjectName_changed(self): self.comboBoxProjectType_changed() self.lineEditSourcePath.setText(self.paratextFolder) self.projectName = self.lineEditProjectName.text() def comboBoxFont_changed(self): self.textFont = self.comboBoxFont.currentText() def lineEditFontSize_changed(self): self.textSize = int(self.lineEditFontSize.text()) def browse_source(self): try: my_dir = QFileDialog.getExistingDirectory(self.dialog, "Open a folder", self.paratextFolder, QFileDialog.ShowDirsOnly) if my_dir: self.paratextFolder = my_dir self.lineEditSourcePath.setText(self.paratextFolder) # except TypeError as detail: # print (detail) except Exception: print("Failed choose Paratext folder: ") # + detail) def browse_audio_path(self): try: my_dir = QFileDialog.getExistingDirectory(self.dialog, "Open a folder", self.audioFolderName, QFileDialog.ShowDirsOnly) if my_dir: self.audioFolderName = my_dir self.lineEditAudioFilesPath.setText(self.audioFolderName) # except TypeError as detail: # print (detail) except Exception: print("Failed choose audio folder: ") # + detail)