From 1f434718ecc6f4c82bd736b0f18ffe38bf93fc85 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 12 Jun 2020 22:00:14 +0200 Subject: [PATCH] Replaced underline format with bold-italic, and all formats now use star, not underscore --- nw/constants/enum.py | 48 ++++++++++++------------ nw/gui/doceditor.py | 89 ++++++++++++++++++++++++++++++++++++++------ nw/gui/mainmenu.py | 24 ++++++------ nw/guimain.py | 4 +- 4 files changed, 116 insertions(+), 49 deletions(-) diff --git a/nw/constants/enum.py b/nw/constants/enum.py index ee33c575..605cc022 100644 --- a/nw/constants/enum.py +++ b/nw/constants/enum.py @@ -68,30 +68,30 @@ class nwItemLayout(Enum): class nwDocAction(Enum): - NO_ACTION = 0 - UNDO = 1 - REDO = 2 - CUT = 3 - COPY = 4 - PASTE = 5 - BOLD = 6 - ITALIC = 7 - U_LINE = 8 - S_QUOTE = 9 - D_QUOTE = 10 - SEL_ALL = 11 - SEL_PARA = 12 - FIND = 13 - REPLACE = 14 - GO_NEXT = 15 - GO_PREV = 16 - REPL_NEXT = 17 - BLOCK_H1 = 18 - BLOCK_H2 = 19 - BLOCK_H3 = 20 - BLOCK_H4 = 21 - BLOCK_COM = 22 - BLOCK_TXT = 23 + NO_ACTION = 0 + UNDO = 1 + REDO = 2 + CUT = 3 + COPY = 4 + PASTE = 5 + ITALIC = 6 + BOLD = 7 + BOLDITALIC = 8 + S_QUOTE = 9 + D_QUOTE = 10 + SEL_ALL = 11 + SEL_PARA = 12 + FIND = 13 + REPLACE = 14 + GO_NEXT = 15 + GO_PREV = 16 + REPL_NEXT = 17 + BLOCK_H1 = 18 + BLOCK_H2 = 19 + BLOCK_H3 = 20 + BLOCK_H4 = 21 + BLOCK_COM = 22 + BLOCK_TXT = 23 # END Enum nwDocAction diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index bd5da37f..e77d89c2 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -509,16 +509,16 @@ class GuiDocEditor(QTextEdit): self.copy() elif theAction == nwDocAction.PASTE: self.paste() - elif theAction == nwDocAction.BOLD: - self._wrapSelection("**","**") elif theAction == nwDocAction.ITALIC: - self._wrapSelection("_","_") - elif theAction == nwDocAction.U_LINE: - self._wrapSelection("__","__") + self._toggleEmph(1) + elif theAction == nwDocAction.BOLD: + self._toggleEmph(2) + elif theAction == nwDocAction.BOLDITALIC: + self._toggleEmph(3) elif theAction == nwDocAction.S_QUOTE: - self._wrapSelection(self.typSQOpen,self.typSQClose) + self._wrapSelection(self.typSQOpen, self.typSQClose) elif theAction == nwDocAction.D_QUOTE: - self._wrapSelection(self.typDQOpen,self.typDQClose) + self._wrapSelection(self.typDQOpen, self.typDQClose) elif theAction == nwDocAction.SEL_ALL: self._makeSelection(QTextCursor.Document) elif theAction == nwDocAction.SEL_PARA: @@ -881,18 +881,20 @@ class GuiDocEditor(QTextEdit): self.bigDoc = False return - def _wrapSelection(self, tBefore, tAfter): + def _wrapSelection(self, tBefore, tAfter=None): """Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection, the autoSelect setting decides the action. AutoSelect will select the word under the cursor before wrapping it. If this feature is disabled, nothing is done. """ - theCursor = self.textCursor() - if self.mainConf.autoSelect and not theCursor.hasSelection(): - theCursor.select(QTextCursor.WordUnderCursor) + if tAfter is None: + tAfter = tBefore + + theCursor = self._autoSelect() if theCursor.hasSelection(): posS = theCursor.selectionStart() posE = theCursor.selectionEnd() + theCursor.clearSelection() theCursor.beginEditBlock() theCursor.setPosition(posE) @@ -900,10 +902,75 @@ class GuiDocEditor(QTextEdit): theCursor.setPosition(posS) theCursor.insertText(tBefore) theCursor.endEditBlock() + + theCursor.setPosition(posE + len(tBefore)) + theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, posE-posS) + self.setTextCursor(theCursor) + else: logger.warning("No selection made, nothing to do") return + def _clearSurrounding(self, theCursor, nChars): + """Clears n characters before and after the cursor. + """ + if theCursor.hasSelection(): + posS = theCursor.selectionStart() + posE = theCursor.selectionEnd() + theCursor.clearSelection() + theCursor.beginEditBlock() + theCursor.setPosition(posS) + for i in range(nChars): + theCursor.deletePreviousChar() + theCursor.setPosition(posE) + for i in range(nChars): + theCursor.deletePreviousChar() + theCursor.endEditBlock() + theCursor.clearSelection() + else: + logger.warning("No selection made, nothing to do") + return + + def _autoSelect(self): + """Returns a cursor which may or may not have a selection based + on user settings and document action. + """ + theCursor = self.textCursor() + if self.mainConf.autoSelect and not theCursor.hasSelection(): + theCursor.select(QTextCursor.WordUnderCursor) + self.setTextCursor(theCursor) + return theCursor + + def _toggleEmph(self, eLevel): + """Toggle emphasis of a given level. + """ + theCursor = self._autoSelect() + if theCursor.hasSelection(): + posS = theCursor.selectionStart() + posE = theCursor.selectionEnd() + + numB = 0 + for n in range(4): + if self.qDocument.characterAt(posS-n-1) == "*": + numB += 1 + else: + break + + numA = 0 + for n in range(4): + if self.qDocument.characterAt(posE+n) == "*": + numA += 1 + else: + break + + cLevel = min(numB, numA) + if cLevel == eLevel: + self._clearSurrounding(theCursor, eLevel) + else: + self._wrapSelection("*"*(eLevel - cLevel)) + + return + def _formatBlock(self, docAction): """Changes the block format of the block under the cursor. """ diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index ece05a58..086261d1 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -515,13 +515,6 @@ class GuiMainMenu(QMenuBar): # Format self.fmtMenu = self.addMenu("&Format") - # Format > Bold Text - self.aFmtBold = QAction("Bold Text", self) - self.aFmtBold.setStatusTip("Make selected text bold") - self.aFmtBold.setShortcut("Ctrl+B") - self.aFmtBold.triggered.connect(lambda: self._docAction(nwDocAction.BOLD)) - self.fmtMenu.addAction(self.aFmtBold) - # Format > Italic Text self.aFmtItalic = QAction("Italic Text", self) self.aFmtItalic.setStatusTip("Make selected text italic") @@ -529,12 +522,19 @@ class GuiMainMenu(QMenuBar): self.aFmtItalic.triggered.connect(lambda: self._docAction(nwDocAction.ITALIC)) self.fmtMenu.addAction(self.aFmtItalic) + # Format > Bold Text + self.aFmtBold = QAction("Bold Text", self) + self.aFmtBold.setStatusTip("Make selected text bold") + self.aFmtBold.setShortcut("Ctrl+B") + self.aFmtBold.triggered.connect(lambda: self._docAction(nwDocAction.BOLD)) + self.fmtMenu.addAction(self.aFmtBold) + # Format > Underline Text - self.aFmtULine = QAction("Underline Text", self) - self.aFmtULine.setStatusTip("Underline selected text") - self.aFmtULine.setShortcut("Ctrl+U") - self.aFmtULine.triggered.connect(lambda: self._docAction(nwDocAction.U_LINE)) - self.fmtMenu.addAction(self.aFmtULine) + self.aFmtBoldIt = QAction("Bold Italic Text", self) + self.aFmtBoldIt.setStatusTip("Make selected text bold and italic") + self.aFmtBoldIt.setShortcut("Ctrl+Shift+B") + self.aFmtBoldIt.triggered.connect(lambda: self._docAction(nwDocAction.BOLDITALIC)) + self.fmtMenu.addAction(self.aFmtBoldIt) # Edit > Separator self.fmtMenu.addSeparator() diff --git a/nw/guimain.py b/nw/guimain.py index 576cd990..cb2f19a2 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -961,9 +961,9 @@ class GuiMain(QMainWindow): self.addAction(self.mainMenu.aEditPaste) self.addAction(self.mainMenu.aSelectAll) self.addAction(self.mainMenu.aSelectPar) - self.addAction(self.mainMenu.aFmtBold) self.addAction(self.mainMenu.aFmtItalic) - self.addAction(self.mainMenu.aFmtULine) + self.addAction(self.mainMenu.aFmtBold) + self.addAction(self.mainMenu.aFmtBoldIt) self.addAction(self.mainMenu.aFmtDQuote) self.addAction(self.mainMenu.aFmtSQuote) self.addAction(self.mainMenu.aFmtHead1)