From 3bfe21468276eefeb65ffa0e27f24fb1113a0c96 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Thu, 18 Jun 2020 23:45:23 +0200 Subject: [PATCH 1/5] Added thin space and thin non-breaking space to unicode class --- nw/constants/constants.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nw/constants/constants.py b/nw/constants/constants.py index b05f8e6d..90e49dfe 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -231,6 +231,8 @@ class nwUnicode: ## Other U_NBSP = "\u00a0" # Non-breaking space + U_THNSP = "\u2009" # Thin space + U_THNBSP = "\u202f" # Thin non-breaking space U_CHECK = "\u2714" # Heavy check mark U_MULT = "\u2715" # Multiplication x @@ -275,6 +277,8 @@ class nwUnicode: ## Other H_NBSP = " " + H_THNSP = " " + H_THNBSP = " " H_CHECK = "✔" H_MULT = "✕" From 61856cec5b60f2813c3e32015ef3ebeebc8e80a5 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 19 Jun 2020 17:34:41 +0200 Subject: [PATCH 2/5] Added new constants for document insert feature --- nw/constants/__init__.py | 8 ++++++-- nw/constants/constants.py | 27 +++++++++++++++++++++++---- nw/constants/enum.py | 13 +++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/nw/constants/__init__.py b/nw/constants/__init__.py index 57761e42..0e90354a 100644 --- a/nw/constants/__init__.py +++ b/nw/constants/__init__.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- from nw.constants.iso import isoLanguage, isoCountry from nw.constants.constants import ( - nwConst, nwRegEx, nwFiles, nwKeyWords, nwLabels, nwQuotes, nwUnicode + nwConst, nwRegEx, nwFiles, nwKeyWords, nwLabels, nwQuotes, nwUnicode, + nwInsertSymbols ) from nw.constants.enum import ( - nwAlert, nwDocAction, nwItemClass, nwItemLayout, nwItemType, nwOutline + nwAlert, nwDocAction, nwItemClass, nwItemLayout, nwItemType, nwOutline, + nwDocInsert ) __all__ = [ @@ -17,10 +19,12 @@ __all__ = [ "nwLabels", "nwQuotes", "nwUnicode", + "nwInsertSymbols", "nwAlert", "nwDocAction", "nwItemClass", "nwItemLayout", "nwItemType", "nwOutline", + "nwDocInsert", ] diff --git a/nw/constants/constants.py b/nw/constants/constants.py index 90e49dfe..1ff5da4f 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -25,7 +25,7 @@ along with this program. If not, see . """ -from nw.constants.enum import nwItemClass, nwItemLayout, nwOutline +from nw.constants.enum import nwItemClass, nwItemLayout, nwOutline, nwDocInsert class nwConst(): @@ -197,7 +197,7 @@ class nwQuotes(): # END Class nwQuotes class nwUnicode: - """Suppoted unicode character constants and translation maps for HTML. + """Supported unicode character constants and translation maps for HTML. """ # Unicode Constants @@ -229,10 +229,12 @@ class nwUnicode: U_EMDASH = "\u2014" # Long dash U_HELLIP = "\u2026" # Ellipsis - ## Other + ## Spaces U_NBSP = "\u00a0" # Non-breaking space U_THNSP = "\u2009" # Thin space U_THNBSP = "\u202f" # Thin non-breaking space + + ## Symbols U_CHECK = "\u2714" # Heavy check mark U_MULT = "\u2715" # Multiplication x @@ -275,10 +277,12 @@ class nwUnicode: H_EMDASH = "—" H_HELLIP = "…" - ## Other + ## Spaces H_NBSP = " " H_THNSP = " " H_THNBSP = " " + + ## Symbols H_CHECK = "✔" H_MULT = "✕" @@ -293,3 +297,18 @@ class nwUnicode: H_LTRIS = "◂" # END Class nwUnicode + +class nwInsertSymbols(): + + SYMBOLS = { + nwDocInsert.NO_INSERT : "", + nwDocInsert.HARD_BREAK : " \n", + nwDocInsert.NB_SPACE : nwUnicode.U_NBSP, + nwDocInsert.THIN_SPACE : nwUnicode.U_THNSP, + nwDocInsert.THIN_NB_SPACE : nwUnicode.U_THNBSP, + nwDocInsert.SHORT_DASH : nwUnicode.U_ENDASH, + nwDocInsert.LONG_DASH : nwUnicode.U_EMDASH, + nwDocInsert.ELLIPSIS : nwUnicode.U_HELLIP, + } + +# END Enum nwDocInsert diff --git a/nw/constants/enum.py b/nw/constants/enum.py index 1f90a928..84f8d4f5 100644 --- a/nw/constants/enum.py +++ b/nw/constants/enum.py @@ -96,6 +96,19 @@ class nwDocAction(Enum): # END Enum nwDocAction +class nwDocInsert(Enum): + + NO_INSERT = 0 + HARD_BREAK = 1 + NB_SPACE = 2 + THIN_SPACE = 3 + THIN_NB_SPACE = 4 + SHORT_DASH = 5 + LONG_DASH = 6 + ELLIPSIS = 7 + +# END Enum nwDocInsert + class nwAlert(Enum): INFO = 0 From 0fc0851def1dadd505a9577673ea407c05d164b3 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 19 Jun 2020 17:35:14 +0200 Subject: [PATCH 3/5] Added insert options and key bindings for seven different symbol and space inserts --- nw/core/tohtml.py | 2 + nw/gui/doceditor.py | 48 +++++------- nw/gui/dochighlight.py | 2 +- nw/gui/mainmenu.py | 161 ++++++++++++++++++++++++++++------------- nw/guimain.py | 27 ++++++- 5 files changed, 156 insertions(+), 84 deletions(-) diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py index 6123ce21..1fd6f00d 100644 --- a/nw/core/tohtml.py +++ b/nw/core/tohtml.py @@ -54,6 +54,8 @@ class ToHtml(Tokenizer): nwUnicode.U_EMDASH : nwUnicode.H_EMDASH, nwUnicode.U_HELLIP : nwUnicode.H_HELLIP, nwUnicode.U_NBSP : nwUnicode.H_NBSP, + nwUnicode.U_THNSP : nwUnicode.H_THNSP, + nwUnicode.U_THNBSP : nwUnicode.H_THNBSP, } self.revDict = {} self.reReplace = [] diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index eadce6ff..35ac09d8 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -48,7 +48,7 @@ from PyQt5.QtWidgets import ( from nw.core import NWDoc from nw.gui.dochighlight import GuiDocHighlighter from nw.core import NWSpellSimple, countWords -from nw.constants import nwUnicode, nwDocAction +from nw.constants import nwUnicode, nwDocAction, nwDocInsert, nwInsertSymbols from nw.common import transferCase logger = logging.getLogger(__name__) @@ -570,6 +570,21 @@ class GuiDocEditor(QTextEdit): )) return + def insertText(self, theInsert): + """Insert a specific type of text at the cursor position. + """ + if isinstance(theInsert, str): + theText = theInsert + elif theInsert in nwInsertSymbols.SYMBOLS: + theText = nwInsertSymbols.SYMBOLS[theInsert] + else: + return False + theCursor = self.textCursor() + theCursor.beginEditBlock() + theCursor.insertText(theText) + theCursor.endEditBlock() + return True + def closeSearch(self): """Close the search box. """ @@ -598,18 +613,7 @@ class GuiDocEditor(QTextEdit): # seems to be capturing the return key. return - if keyEvent.modifiers() == Qt.ShiftModifier: - theKey = keyEvent.key() - if theKey == Qt.Key_Return: - self._insertHardBreak() - elif theKey == Qt.Key_Enter: - self._insertHardBreak() - elif theKey == Qt.Key_Space: - self._insertNonBreakingSpace() - else: - QTextEdit.keyPressEvent(self, keyEvent) - else: - QTextEdit.keyPressEvent(self, keyEvent) + QTextEdit.keyPressEvent(self, keyEvent) return @@ -797,24 +801,6 @@ class GuiDocEditor(QTextEdit): return True - def _insertHardBreak(self): - """Inserts a hard line break at the cursor position. - """ - theCursor = self.textCursor() - theCursor.beginEditBlock() - theCursor.insertText(" \n") - theCursor.endEditBlock() - return - - def _insertNonBreakingSpace(self): - """Inserts a non-breaking space at the cursor position. - """ - theCursor = self.textCursor() - theCursor.beginEditBlock() - theCursor.insertText(nwUnicode.U_NBSP) - theCursor.endEditBlock() - return - def _openSpellContext(self): """Opens the spell check context menu at the current point of the cursor. diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index a76c9646..4acc0e7a 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -132,7 +132,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): # Non-Breaking Spaces self.hRules.append(( - "[%s]+" % nwUnicode.U_NBSP, { + "[%s%s]+" % (nwUnicode.U_NBSP, nwUnicode.U_THNBSP), { 0 : self.hStyles["nobreak"], } )) diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 720eefae..7f7c9164 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -28,12 +28,12 @@ import logging import nw -from PyQt5.QtCore import QUrl +from PyQt5.QtCore import Qt, QUrl from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QMenuBar, QAction, QMessageBox from nw.gui.about import GuiAbout -from nw.constants import nwItemType, nwItemClass, nwDocAction +from nw.constants import nwItemType, nwItemClass, nwDocAction, nwDocInsert logger = logging.getLogger(__name__) @@ -50,8 +50,9 @@ class GuiMainMenu(QMenuBar): self._buildProjectMenu() self._buildDocumentMenu() self._buildEditMenu() - self._buildViewMenu() + self._buildInsertMenu() self._buildFormatMenu() + self._buildViewMenu() self._buildToolsMenu() self._buildHelpMenu() @@ -59,6 +60,7 @@ class GuiMainMenu(QMenuBar): self._docAction = self.theParent.passDocumentAction self._moveTreeItem = self.theParent.treeView.moveTreeItem self._newTreeItem = self.theParent.treeView.newTreeItem + self._docInsert = self.theParent.docEditor.insertText logger.debug("GuiMainMenu initialisation complete") @@ -341,53 +343,6 @@ class GuiMainMenu(QMenuBar): return - def _buildViewMenu(self): - - # View - self.viewMenu = self.addMenu("&View") - - # View > TreeView - self.aFocusTree = QAction("Focus Project Tree", self) - self.aFocusTree.setStatusTip("Move focus to project tree") - self.aFocusTree.setShortcut("Alt+1") - self.aFocusTree.triggered.connect(lambda : self.theParent.setFocus(1)) - self.viewMenu.addAction(self.aFocusTree) - - # View > Document Pane 1 - self.aFocusEditor = QAction("Focus Document Editor", self) - self.aFocusEditor.setStatusTip("Move focus to left document pane") - self.aFocusEditor.setShortcut("Alt+2") - self.aFocusEditor.triggered.connect(lambda : self.theParent.setFocus(2)) - self.viewMenu.addAction(self.aFocusEditor) - - # View > Document Pane 2 - self.aFocusView = QAction("Focus Document Viewer", self) - self.aFocusView.setStatusTip("Move focus to right document pane") - self.aFocusView.setShortcut("Alt+3") - self.aFocusView.triggered.connect(lambda : self.theParent.setFocus(3)) - self.viewMenu.addAction(self.aFocusView) - - # View > Separator - self.viewMenu.addSeparator() - - # View > Toggle Distraction Free Mode - self.aZenMode = QAction("Zen Mode", self) - self.aZenMode.setStatusTip("Toggles distraction free mode, only showing text editor") - self.aZenMode.setShortcut("F8") - self.aZenMode.setCheckable(True) - self.aZenMode.setChecked(self.theParent.isZenMode) - self.aZenMode.toggled.connect(self.theParent.toggleZenMode) - self.viewMenu.addAction(self.aZenMode) - - # View > Toggle Full Screen - self.aFullScreen = QAction("Full Screen Mode", self) - self.aFullScreen.setStatusTip("Maximises the main window") - self.aFullScreen.setShortcut("F11") - self.aFullScreen.triggered.connect(self.theParent.toggleFullScreenMode) - self.viewMenu.addAction(self.aFullScreen) - - return - def _buildEditMenu(self): # Edit @@ -497,6 +452,65 @@ class GuiMainMenu(QMenuBar): return + def _buildInsertMenu(self): + + # Insert + self.insertMenu = self.addMenu("&Insert") + + # Insert > Short Dash + self.aInsENDash = QAction("Short Dash", self) + self.aInsENDash.setStatusTip("Insert short dash") + self.aInsENDash.setShortcut("Ctrl+K, -") + self.aInsENDash.triggered.connect(lambda: self._docInsert(nwDocInsert.SHORT_DASH)) + self.insertMenu.addAction(self.aInsENDash) + + # Insert > Long Dash + self.aInsEMDash = QAction("Long Dash", self) + self.aInsEMDash.setStatusTip("Insert long dash") + self.aInsEMDash.setShortcut("Ctrl+K, _") + self.aInsEMDash.triggered.connect(lambda: self._docInsert(nwDocInsert.LONG_DASH)) + self.insertMenu.addAction(self.aInsEMDash) + + # Insert > Ellipsis + self.aInsEllipsis = QAction("Ellipsis", self) + self.aInsEllipsis.setStatusTip("Insert ellipsis") + self.aInsEllipsis.setShortcut("Ctrl+K, .") + self.aInsEllipsis.triggered.connect(lambda: self._docInsert(nwDocInsert.ELLIPSIS)) + self.insertMenu.addAction(self.aInsEllipsis) + + # Insert > Separator + self.insertMenu.addSeparator() + + # Insert > Hard Line Break + self.aInsHardBreak = QAction("Hard Line Break", self) + self.aInsHardBreak.setStatusTip("Insert a hard line break") + self.aInsHardBreak.setShortcut("Ctrl+K, Return") + self.aInsHardBreak.triggered.connect(lambda: self._docInsert(nwDocInsert.HARD_BREAK)) + self.insertMenu.addAction(self.aInsHardBreak) + + # Insert > Non-Breaking Space + self.aInsNBSpace = QAction("Non-Breaking Space", self) + self.aInsNBSpace.setStatusTip("Insert a non-breaking space") + self.aInsNBSpace.setShortcut("Ctrl+K, Space") + self.aInsNBSpace.triggered.connect(lambda: self._docInsert(nwDocInsert.NB_SPACE)) + self.insertMenu.addAction(self.aInsNBSpace) + + # Insert > Thin Space + self.aInsThinSpace = QAction("Thin Space", self) + self.aInsThinSpace.setStatusTip("Insert a thin space") + self.aInsThinSpace.setShortcut("Ctrl+K, Shift+Space") + self.aInsThinSpace.triggered.connect(lambda: self._docInsert(nwDocInsert.THIN_SPACE)) + self.insertMenu.addAction(self.aInsThinSpace) + + # Insert > Thin Non-Breaking Space + self.aInsThinNBSpace = QAction("Thin Non-Breaking Space", self) + self.aInsThinNBSpace.setStatusTip("Insert a thin non-breaking space") + self.aInsThinNBSpace.setShortcut("Ctrl+K, Ctrl+Space") + self.aInsThinNBSpace.triggered.connect(lambda: self._docInsert(nwDocInsert.THIN_NB_SPACE)) + self.insertMenu.addAction(self.aInsThinNBSpace) + + return + def _buildFormatMenu(self): # Format @@ -594,6 +608,53 @@ class GuiMainMenu(QMenuBar): return + def _buildViewMenu(self): + + # View + self.viewMenu = self.addMenu("&View") + + # View > TreeView + self.aFocusTree = QAction("Focus Project Tree", self) + self.aFocusTree.setStatusTip("Move focus to project tree") + self.aFocusTree.setShortcut("Alt+1") + self.aFocusTree.triggered.connect(lambda : self.theParent.setFocus(1)) + self.viewMenu.addAction(self.aFocusTree) + + # View > Document Pane 1 + self.aFocusEditor = QAction("Focus Document Editor", self) + self.aFocusEditor.setStatusTip("Move focus to left document pane") + self.aFocusEditor.setShortcut("Alt+2") + self.aFocusEditor.triggered.connect(lambda : self.theParent.setFocus(2)) + self.viewMenu.addAction(self.aFocusEditor) + + # View > Document Pane 2 + self.aFocusView = QAction("Focus Document Viewer", self) + self.aFocusView.setStatusTip("Move focus to right document pane") + self.aFocusView.setShortcut("Alt+3") + self.aFocusView.triggered.connect(lambda : self.theParent.setFocus(3)) + self.viewMenu.addAction(self.aFocusView) + + # View > Separator + self.viewMenu.addSeparator() + + # View > Toggle Distraction Free Mode + self.aZenMode = QAction("Zen Mode", self) + self.aZenMode.setStatusTip("Toggles distraction free mode, only showing text editor") + self.aZenMode.setShortcut("F8") + self.aZenMode.setCheckable(True) + self.aZenMode.setChecked(self.theParent.isZenMode) + self.aZenMode.toggled.connect(self.theParent.toggleZenMode) + self.viewMenu.addAction(self.aZenMode) + + # View > Toggle Full Screen + self.aFullScreen = QAction("Full Screen Mode", self) + self.aFullScreen.setStatusTip("Maximises the main window") + self.aFullScreen.setShortcut("F11") + self.aFullScreen.triggered.connect(self.theParent.toggleFullScreenMode) + self.viewMenu.addAction(self.aFullScreen) + + return + def _buildToolsMenu(self): # Tools diff --git a/nw/guimain.py b/nw/guimain.py index 70a6ba0b..a82d5a99 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -966,12 +966,15 @@ class GuiMain(QMainWindow): """Connect to the main window all menu actions that need to be available also when the main menu is hidden. """ + # Project self.addAction(self.mainMenu.aSaveProject) self.addAction(self.mainMenu.aExitNW) + + # Document self.addAction(self.mainMenu.aSaveDoc) self.addAction(self.mainMenu.aFileDetails) - self.addAction(self.mainMenu.aZenMode) - self.addAction(self.mainMenu.aFullScreen) + + # Edit self.addAction(self.mainMenu.aEditUndo) self.addAction(self.mainMenu.aEditRedo) self.addAction(self.mainMenu.aEditCut) @@ -979,6 +982,17 @@ class GuiMain(QMainWindow): self.addAction(self.mainMenu.aEditPaste) self.addAction(self.mainMenu.aSelectAll) self.addAction(self.mainMenu.aSelectPar) + + # Insert + self.addAction(self.mainMenu.aInsENDash) + self.addAction(self.mainMenu.aInsEMDash) + self.addAction(self.mainMenu.aInsEllipsis) + self.addAction(self.mainMenu.aInsHardBreak) + self.addAction(self.mainMenu.aInsNBSpace) + self.addAction(self.mainMenu.aInsThinSpace) + self.addAction(self.mainMenu.aInsThinNBSpace) + + # Format self.addAction(self.mainMenu.aFmtItalic) self.addAction(self.mainMenu.aFmtBold) self.addAction(self.mainMenu.aFmtBoldIt) @@ -990,10 +1004,19 @@ class GuiMain(QMainWindow): self.addAction(self.mainMenu.aFmtHead4) self.addAction(self.mainMenu.aFmtComment) self.addAction(self.mainMenu.aFmtNoFormat) + + # View + self.addAction(self.mainMenu.aZenMode) + self.addAction(self.mainMenu.aFullScreen) + + # Tools self.addAction(self.mainMenu.aSpellCheck) self.addAction(self.mainMenu.aReRunSpell) self.addAction(self.mainMenu.aPreferences) + + # Help self.addAction(self.mainMenu.aHelp) + return True def _setWindowTitle(self, projName=None): From fdf79157471abb74781185dbb13d46cb263492c5 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 19 Jun 2020 17:35:35 +0200 Subject: [PATCH 4/5] Updated sample text with extra descriptions --- sample/content/636b6aa9b697b.nwd | 4 +++- sample/nwProject.nwx | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sample/content/636b6aa9b697b.nwd b/sample/content/636b6aa9b697b.nwd index 4916b753..0ae22a00 100644 --- a/sample/content/636b6aa9b697b.nwd +++ b/sample/content/636b6aa9b697b.nwd @@ -13,7 +13,9 @@ In addition, the editor supports automatic formatting of “quotes”, both doub If you have the need for it, you can also add text that can be automatically replaced by other text when you generate a preview or export the project. Now, let’s auto-replace this A with , and this C with . While is just . Press Ctrl+R to see what this looks like in the view pane. -The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. +The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. Regular dashes are also supported – and can be automatically inserted when typing two hyphens.⎄ + +Thin spaces and thin non-breaking spaces are also supported from the Insert menu, and can be used to separate numbers from their units, like: 25 kg. #### Some Section Here diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index aeba369e..23daf66e 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,21 +1,21 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 332 - 56 - 10692 + 404 + 70 + 14966 False True True 636b6aa9b697b - 636b6aa9b697b - 927 + bb2c23b3c42cc + 967 B E @@ -114,10 +114,10 @@ 1st Draft True SCENE - 1240 - 223 - 7 - 403 + 1484 + 263 + 8 + 1087 Another Scene From ee23f937f20af10f5b3e016667529010ffa08723 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 19 Jun 2020 19:51:23 +0200 Subject: [PATCH 5/5] Added issues tracker menu entry, and made a few minor changes --- nw/__init__.py | 1 + nw/gui/mainmenu.py | 34 ++++++++++++++++++++++++++------ sample/content/636b6aa9b697b.nwd | 2 +- sample/nwProject.nwx | 12 +++++------ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/nw/__init__.py b/nw/__init__.py index 6ab06265..92fd0ac2 100644 --- a/nw/__init__.py +++ b/nw/__init__.py @@ -47,6 +47,7 @@ __maintainer__ = "Veronica Berglyd Olsen" __email__ = "code@vkbo.net" __status__ = "Pre-Release" __url__ = "https://github.com/vkbo/novelWriter" +__issuesurl__ = "https://github.com/vkbo/novelWriter/issues" __domain__ = "novelwriter.io" __docurl__ = "https://novelwriter.readthedocs.io" __credits__ = [ diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 7f7c9164..d831da81 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -28,7 +28,7 @@ import logging import nw -from PyQt5.QtCore import Qt, QUrl +from PyQt5.QtCore import QUrl from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QMenuBar, QAction, QMessageBox @@ -99,6 +99,8 @@ class GuiMainMenu(QMenuBar): ## def _menuExit(self): + """Exit novelWriter. + """ self.theParent.closeMain() return @@ -125,19 +127,33 @@ class GuiMainMenu(QMenuBar): return True def _showAboutQt(self): + """Show Qt's own About dialog. + """ msgBox = QMessageBox() msgBox.aboutQt(self.theParent,"About Qt") return True def _openHelp(self): + """Open the documentation URL in the system's default browser. + """ QDesktopServices.openUrl(QUrl(nw.__docurl__)) return True + def _openIssue(self): + """Open the issue tracker URL in the system's default browser. + """ + QDesktopServices.openUrl(QUrl(nw.__issuesurl__)) + return True + def _showDocumentLocation(self): + """Open the dialog showing the location of the editor document. + """ self.theParent.docEditor.revealLocation() return True def _doBackup(self): + """Call the backup function for the project. + """ self.theProject.zipIt(True) return True @@ -230,14 +246,14 @@ class GuiMainMenu(QMenuBar): self.projMenu.addSeparator() # Project > Edit - self.aEditItem = QAction("&Edit Project Item", self) + self.aEditItem = QAction("Edit Project Item", self) self.aEditItem.setStatusTip("Change item settings") self.aEditItem.setShortcuts(["Ctrl+E", "F2"]) self.aEditItem.triggered.connect(self.theParent.editItem) self.projMenu.addAction(self.aEditItem) # Project > Delete - self.aDeleteItem = QAction("&Delete Project Item", self) + self.aDeleteItem = QAction("Delete Project Item", self) self.aDeleteItem.setStatusTip("Delete selected item") self.aDeleteItem.setShortcut("Ctrl+Del") self.aDeleteItem.triggered.connect(lambda : self.theParent.treeView.deleteItem(None)) @@ -267,21 +283,21 @@ class GuiMainMenu(QMenuBar): self.docuMenu = self.addMenu("&Document") # Document > New - self.aNewDoc = QAction("&New Document", self) + self.aNewDoc = QAction("New Document", self) self.aNewDoc.setStatusTip("Create new document") self.aNewDoc.setShortcut("Ctrl+N") self.aNewDoc.triggered.connect(lambda : self._newTreeItem(nwItemType.FILE, None)) self.docuMenu.addAction(self.aNewDoc) # Document > Open - self.aOpenDoc = QAction("&Open Document", self) + self.aOpenDoc = QAction("Open Document", self) self.aOpenDoc.setStatusTip("Open selected document") self.aOpenDoc.setShortcut("Ctrl+O") self.aOpenDoc.triggered.connect(self.theParent.openSelectedItem) self.docuMenu.addAction(self.aOpenDoc) # Document > Save - self.aSaveDoc = QAction("&Save Document", self) + self.aSaveDoc = QAction("Save Document", self) self.aSaveDoc.setStatusTip("Save current document") self.aSaveDoc.setShortcut("Ctrl+S") self.aSaveDoc.triggered.connect(self.theParent.saveDocument) @@ -764,6 +780,12 @@ class GuiMainMenu(QMenuBar): self.aHelp.triggered.connect(self._openHelp) self.helpMenu.addAction(self.aHelp) + # Document > Report Issue + self.aIssue = QAction("Report an Issue", self) + self.aIssue.setStatusTip("View online documentation") + self.aIssue.triggered.connect(self._openIssue) + self.helpMenu.addAction(self.aIssue) + return # END Class GuiMainMenu diff --git a/sample/content/636b6aa9b697b.nwd b/sample/content/636b6aa9b697b.nwd index 0ae22a00..394a96ce 100644 --- a/sample/content/636b6aa9b697b.nwd +++ b/sample/content/636b6aa9b697b.nwd @@ -13,7 +13,7 @@ In addition, the editor supports automatic formatting of “quotes”, both doub If you have the need for it, you can also add text that can be automatically replaced by other text when you generate a preview or export the project. Now, let’s auto-replace this A with , and this C with . While is just . Press Ctrl+R to see what this looks like in the view pane. -The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. Regular dashes are also supported – and can be automatically inserted when typing two hyphens.⎄ +The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. Regular dashes are also supported – and can be automatically inserted when typing two hyphens. Thin spaces and thin non-breaking spaces are also supported from the Insert menu, and can be used to separate numbers from their units, like: 25 kg. diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index 23daf66e..4ce89213 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,13 +1,13 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 404 - 70 - 14966 + 407 + 71 + 15118 False @@ -114,10 +114,10 @@ 1st Draft True SCENE - 1484 + 1483 263 8 - 1087 + 1086 Another Scene