Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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())
Exemplo n.º 3
0
    def create_ui(self):
        # 1.文字标签
        # QLabel(显示的文字, 父标签/放到哪个窗口上)
        label1 = QLabel('用户名:', self)
        # 一般不常用的移动坐标
        label1.move(50, 10)

        # 2.按钮
        btn1 = QPushButton('登录', self)
        btn1.move(50, 50)
        # css语法:选择器{属性1:属性值1; 属性2:属性值2;..}
        # color - 字体颜色,对应的值:颜色单词, rbg(255, 0, 0)
        #
        btn1.setStyleSheet('QPushButton{}')
        btn2 = QRadioButton('男', self)
        btn2.move(50, 100)
        btn3 = QCheckBox('篮球', self)
        btn3.move(50, 150)
        btn4 = QCommandLinkButton('hello', 'hellowword', self)
        btn4.move(50, 200)

        b1 = QDialogButtonBox.StandardButton.Ok
        b2 = QDialogButtonBox.StandardButton.Cancel
        btn5 = QDialogButtonBox(b2, self)
        btn5.move(50, 300)

        # 3.输入框
        input1 = QLineEdit(self)
        input1.move(150, 10)
        input2 = QLineEdit('admin', self)
        input2.move(150, 50)
        input1.setText('张三')
        # 富文本
        input3 = QTextEdit('张三', self)
        input3.move(50, 300)
        # 设置成只读
        input3.setReadOnly(True)
        # 只能显示纯文本
        input4 = QPlainTextEdit(self)
        input4.move(300, 10)
        # 输入数值
        input5 = QSpinBox(self)
        input5.move(100, 100)
        input5.setMinimum(10)
        input5.setMaximum(20)
        input5.setValue(15)
        print(input5.value())  # 获取当前值
        # 输入小数
        input6 = QDoubleSpinBox(self)
        input6.move(100, 150)
        # 下拉菜单
        input7 = QComboBox(self)
        input7.addItems(['item1', 'item2'])
        input7.move(150, 200)
        print(input7.currentText())  # 获取当前选中的选项,适用input8
        input8 = QFontComboBox(self)
        input8.move(350, 300)
        input8.setCurrentIndex(2)
        print(input8.currentText())
        label1.setFont(input8.currentFont())
        # 日期选择
        input9 = QDateEdit(date.today(), self)
        input9.move(300, 400)
        # 选择颜色
        input10 = QColorDialog(self)
        input10.move(400, 400)
        # input10.show()

        input11 = QDial(self)
        input11.move(300, 200)

        input12 = QSlider(self)
        input12.move(430, 350)
        input12.setMaximum(100)
        input12.setMinimum(-100)
        input12.setValue(20)
        input12.setOrientation(Qt.Horizontal)  # 设置为水平方向
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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)