diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b8065bd..93f9a24f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,18 +17,37 @@ * Added the file's class and layout to the meta data string added as the first line of saved document files. This meta data is only used to restore the file meta information into the project if it was lost from the project file. It is also useful information when reading the file in external tools. PR #308. -## Version 0.8 [2020-xx-xx] +## Version 0.8 [2020-06-14] + +**Bugfixes** + +* The HTML converter, used for the document view window as well as the Build Novel Project tool, would crash novelWriter if a file included an `@tag:` entry with no actual tag name following it. In addition to fixing this issue, the call to the converter is now also wrapped in a `try/except` construct to prevent crashes caused by potential edge cases in document content. If the rendering fails, the view window will show an error message instead of the intended document. Issue #298, PR #299. +* Clipping of the descended part of fonts in the document title bar has been fixed. Issue #295, PR #300. +* When clicking a tag in the editor while the viewer was closed, nothing would happen. Now, the viewer is first opened before navigating to the source of the reference tag. Issue #294, PR #306. +* The missing optional rendering of synopsis comments in the document view panel has been added. Mentioned in Issue #301, PR #311. **User Interface** * A details panel below the Outline tree view has been added. The panel shows all the information of a selected row in the tree view above, including hidden columns, and some additional information. The tags and references also become clickable links that when clicked will open in the document viewer. PR #281. +* Icons have been added to the Title and Document columns in the Outline. The titles get a new icon indicating the header level, while the documents get the already existing document icon. PR #302. * Added a context menu to the project tree for easier access to some of the most use actions on the tree. PR #282. -* Improved the support for High DPI screens. Margins and box sizes that are hardcoded should now scale. User settings should also scale back and forth when switching between scale factors. Issue #280, PR #285. +* Improved the support for High DPI screens. Margins and box sizes that were hardcoded should now scale. User settings should also scale back and forth when switching between scale factors. Issue #280, PR #285. +* The total edit time of a project is no displayed on the Details tab of the Project Settings dialog. PR #290. +* The title bar in the document editor now has a full screen button and a close button, and in the document viewer a reload button and a close button. The full screen button toggles the distraction free mode, and the reload button regenerates the document being viewed to update any changes that may have been made to it. PRs #293, #300, #303 and #306. +* The References panel below the document viewer has been redesigned. It now sits in a resizeable panel below the document, and its controls sit in a footer bar in the document itself. The functionality of the feature is otherwise unchanged, but the buttons have received new icons. PRs #304 and #306. +* The option to render comments and synopsis in the document view panel has been added to Preferences. The toggle option for comments that was previously in the menu has been removed. PR #311. **Project Structure** * The way GUI states of switches, column widths, etc., is saved has been improved a bit during the High DPI updates. PRs #285 and #286. * Some settings have been moved around to more appropriate sections in the project XML file. The project load function still reads the values from the previous location if opening an older project file. PR #288. +* A file opened in the Trash folder is no longer "Read Only". The feature was rather arbitrary, and also required a GUI element to notify the user of the fact. Any file can now be edited. PR #292. + +**Code Structure** + +* The core classes making up the project itself were previously merged into a single source code file. This file was getting a bit big, so they have been split up again. PR #289. +* A lot of Inkscape meta data has been removed from the SVG icons, reducing the file sizes quite a bit. PR #291. +* Opening and closing of files are now properly handled also when using the ConfigParser tool. Previously, files were not properly closed after the content had been read, leaving the handles open until the Python garbage collector handled them. PR #300. ## Version 0.7.1 [2020-06-06] diff --git a/nw/__init__.py b/nw/__init__.py index 24d3a261..6ab06265 100644 --- a/nw/__init__.py +++ b/nw/__init__.py @@ -42,7 +42,7 @@ __copyright__ = "Copyright 2018–2020, Veronica Berglyd Olsen" __license__ = "GPLv3" __version__ = "0.9.0rc1" __hexversion__ = "0x000900c1" -__date__ = "2020-06-01" +__date__ = "2020-06-14" __maintainer__ = "Veronica Berglyd Olsen" __email__ = "code@vkbo.net" __status__ = "Pre-Release" diff --git a/nw/config.py b/nw/config.py index a1e222dd..4f690be3 100644 --- a/nw/config.py +++ b/nw/config.py @@ -141,6 +141,7 @@ class Config: ## State self.showRefPanel = True self.viewComments = True + self.viewSynopsis = True # Check Qt5 Versions verQt = splitVersionNumber(QT_VERSION_STR) @@ -478,6 +479,9 @@ class Config: self.viewComments = self._parseLine( cnfParse, cnfSec, "viewcomments", self.CNF_BOOL, self.viewComments ) + self.viewSynopsis = self._parseLine( + cnfParse, cnfSec, "viewsynopsis", self.CNF_BOOL, self.viewSynopsis + ) ## Path cnfSec = "Path" @@ -569,6 +573,7 @@ class Config: cnfParse.add_section(cnfSec) cnfParse.set(cnfSec,"showrefpanel",str(self.showRefPanel)) cnfParse.set(cnfSec,"viewcomments",str(self.viewComments)) + cnfParse.set(cnfSec,"viewsynopsis",str(self.viewSynopsis)) ## Path cnfSec = "Path" @@ -753,11 +758,6 @@ class Config: self.confChanged = True return self.showRefPanel - def setViewComments(self, checkState): - self.viewComments = checkState - self.confChanged = True - return self.viewComments - def getErrData(self): errMessage = "
".join(self.errData) self.hasError = False diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py index 22dde913..6123ce21 100644 --- a/nw/core/tohtml.py +++ b/nw/core/tohtml.py @@ -66,7 +66,7 @@ class ToHtml(Tokenizer): # Setters ## - def setPreview(self, forPreview, doComments): + def setPreview(self, forPreview, doComments, doSynopsis): """If we're using this class to generate markdown preview, we need to make a few changes to formatting, which is managed by these flags. @@ -75,6 +75,7 @@ class ToHtml(Tokenizer): self.genMode = self.M_PREVIEW self.doKeywords = True self.doComments = doComments + self.doSynopsis = doSynopsis self.repDict["\t"] = " "*8 self._buildRegEx() return @@ -301,18 +302,18 @@ class ToHtml(Tokenizer): def _formatSynopsis(self, tText): """Apply HTML formatting to synopsis. """ - if self.genMode == self.M_EXPORT: - return "

Synopsis: %s

\n" % tText + if self.genMode == self.M_PREVIEW: + return "

Synopsis: %s

\n" % tText else: - return "

%s

\n" % tText + return "

Synopsis: %s

\n" % tText def _formatComments(self, tText): """Apply HTML formatting to comments. """ - if self.genMode == self.M_EXPORT: - return "

Comment: %s

\n" % tText - else: + if self.genMode == self.M_PREVIEW: return "

%s

\n" % tText + else: + return "

Comment: %s

\n" % tText def _formatKeywords(self, tText): """Apply HTML formatting to keywords. diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py index a2884dab..1059c277 100644 --- a/nw/gui/docviewer.py +++ b/nw/gui/docviewer.py @@ -136,7 +136,7 @@ class GuiDocViewer(QTextBrowser): logger.debug("Generating preview for item %s" % tHandle) sPos = self.verticalScrollBar().value() aDoc = ToHtml(self.theProject, self.theParent) - aDoc.setPreview(True, self.mainConf.viewComments) + aDoc.setPreview(True, self.mainConf.viewComments, self.mainConf.viewSynopsis) aDoc.setLinkHeaders(True) # Be extra careful here to prevent crashes when first opening a @@ -366,6 +366,10 @@ class GuiDocViewer(QTextBrowser): " margin-left: 1em;" " margin-right: 1em;" "}}\n" + ".synopsis {{" + " color: rgb({mColR},{mColG},{mColB});" + " font-wright: bold;" + "}}\n" ).format( textSize = self.mainConf.textSize, preSize = self.mainConf.textSize*0.9, @@ -387,6 +391,9 @@ class GuiDocViewer(QTextBrowser): kColR = self.theTheme.colKey[0], kColG = self.theTheme.colKey[1], kColB = self.theTheme.colKey[2], + mColR = self.theTheme.colMod[0], + mColG = self.theTheme.colMod[1], + mColB = self.theTheme.colMod[2], ) self.qDocument.setDefaultStyleSheet(styleSheet) diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 3ea9a85d..720eefae 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -114,11 +114,6 @@ class GuiMainMenu(QMenuBar): self.theProject.setAutoOutline(theMode) return True - def _toggleViewComments(self): - self.mainConf.setViewComments(self.aViewDocComments.isChecked()) - self.theParent.docViewer.reloadText() - return True - def _showAbout(self): """Show the about dialog. """ @@ -314,14 +309,6 @@ class GuiMainMenu(QMenuBar): self.aCloseView.triggered.connect(self.theParent.closeDocViewer) self.docuMenu.addAction(self.aCloseView) - # Document > Toggle View Comments - self.aViewDocComments = QAction("Show Comments", self) - self.aViewDocComments.setStatusTip("Show comments in view panel") - self.aViewDocComments.setCheckable(True) - self.aViewDocComments.setChecked(self.mainConf.viewComments) - self.aViewDocComments.toggled.connect(self._toggleViewComments) - self.docuMenu.addAction(self.aViewDocComments) - # Document > Separator self.docuMenu.addSeparator() diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py index 17487a31..5c0ef235 100644 --- a/nw/gui/preferences.py +++ b/nw/gui/preferences.py @@ -62,7 +62,7 @@ class GuiPreferences(PagedDialog): self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent) self.addTab(self.tabGeneral, "General") - self.addTab(self.tabLayout, "Layout") + self.addTab(self.tabLayout, "Text Layout") self.addTab(self.tabEditing, "Editor") self.addTab(self.tabAutoRep, "Auto-Replace") @@ -506,6 +506,26 @@ class GuiConfigEditLayoutTab(QWidget): self.showLineEndings ) + # Render Options + # ============== + self.mainForm.addGroupLabel("Render Text") + + ## Render Comments + self.viewComments = QSwitch() + self.viewComments.setChecked(self.mainConf.viewComments) + self.mainForm.addRow( + "Render comments in document view panel", + self.viewComments + ) + + ## Render Synopsis + self.viewSynopsis = QSwitch() + self.viewSynopsis.setChecked(self.mainConf.viewSynopsis) + self.mainForm.addRow( + "Render synopsis in document view panel", + self.viewSynopsis + ) + return def saveValues(self): @@ -523,6 +543,8 @@ class GuiConfigEditLayoutTab(QWidget): tabWidth = self.tabWidth.value() showTabsNSpaces = self.showTabsNSpaces.isChecked() showLineEndings = self.showLineEndings.isChecked() + viewComments = self.viewComments.isChecked() + viewSynopsis = self.viewSynopsis.isChecked() self.mainConf.textFont = textFont self.mainConf.textSize = textSize @@ -534,6 +556,8 @@ class GuiConfigEditLayoutTab(QWidget): self.mainConf.tabWidth = tabWidth self.mainConf.showTabsNSpaces = showTabsNSpaces self.mainConf.showLineEndings = showLineEndings + self.mainConf.viewComments = viewComments + self.mainConf.viewSynopsis = viewSynopsis self.mainConf.confChanged = True diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index bafeaaed..ba0f2db7 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -1,5 +1,5 @@ [Main] -timestamp = 2020-06-09 23:05:17 +timestamp = 2020-06-13 22:59:36 theme = default syntax = default_light icons = typicons_colour_light @@ -54,6 +54,7 @@ askbeforebackup = True [State] showrefpanel = True viewcomments = True +viewsynopsis = True [Path] lastpath = diff --git a/tests/test_config.py b/tests/test_config.py index a8562976..7f0226cc 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -70,6 +70,7 @@ def testConfigSetTreeColWidths(nwTemp,nwRef): assert theConf.setTreeColWidths([0, 0, 0]) assert theConf.confChanged assert theConf.setTreeColWidths([120, 30, 50]) + assert theConf.setProjColWidths([140, 55, 140]) assert theConf.saveConfig() assert cmpFiles(tmpConf, refConf, [2]) assert not theConf.confChanged @@ -82,6 +83,8 @@ def testConfigSetPanePos(nwTemp,nwRef): assert theConf.confChanged assert theConf.setMainPanePos([300, 800]) assert theConf.setDocPanePos([400, 400]) + assert theConf.setViewPanePos([500, 150]) + assert theConf.setOutlinePanePos([500, 150]) assert theConf.saveConfig() assert cmpFiles(tmpConf, refConf, [2]) assert not theConf.confChanged @@ -92,8 +95,6 @@ def testConfigFlags(nwTemp,nwRef): refConf = path.join(nwRef, "novelwriter.conf") assert not theConf.setShowRefPanel(False) assert theConf.setShowRefPanel(True) - assert not theConf.setViewComments(False) - assert theConf.setViewComments(True) assert theConf.confChanged assert theConf.saveConfig() assert cmpFiles(tmpConf, refConf, [2])