Merge branch 'master' into dev

This commit is contained in:
Veronica K. B. Olsen
2020-06-14 16:10:51 +02:00
9 changed files with 73 additions and 33 deletions
+21 -2
View File
@@ -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. * 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** **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. * 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. * 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** **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. * 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. * 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] ## Version 0.7.1 [2020-06-06]
+1 -1
View File
@@ -42,7 +42,7 @@ __copyright__ = "Copyright 20182020, Veronica Berglyd Olsen"
__license__ = "GPLv3" __license__ = "GPLv3"
__version__ = "0.9.0rc1" __version__ = "0.9.0rc1"
__hexversion__ = "0x000900c1" __hexversion__ = "0x000900c1"
__date__ = "2020-06-01" __date__ = "2020-06-14"
__maintainer__ = "Veronica Berglyd Olsen" __maintainer__ = "Veronica Berglyd Olsen"
__email__ = "code@vkbo.net" __email__ = "code@vkbo.net"
__status__ = "Pre-Release" __status__ = "Pre-Release"
+5 -5
View File
@@ -141,6 +141,7 @@ class Config:
## State ## State
self.showRefPanel = True self.showRefPanel = True
self.viewComments = True self.viewComments = True
self.viewSynopsis = True
# Check Qt5 Versions # Check Qt5 Versions
verQt = splitVersionNumber(QT_VERSION_STR) verQt = splitVersionNumber(QT_VERSION_STR)
@@ -478,6 +479,9 @@ class Config:
self.viewComments = self._parseLine( self.viewComments = self._parseLine(
cnfParse, cnfSec, "viewcomments", self.CNF_BOOL, self.viewComments cnfParse, cnfSec, "viewcomments", self.CNF_BOOL, self.viewComments
) )
self.viewSynopsis = self._parseLine(
cnfParse, cnfSec, "viewsynopsis", self.CNF_BOOL, self.viewSynopsis
)
## Path ## Path
cnfSec = "Path" cnfSec = "Path"
@@ -569,6 +573,7 @@ class Config:
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"showrefpanel",str(self.showRefPanel)) cnfParse.set(cnfSec,"showrefpanel",str(self.showRefPanel))
cnfParse.set(cnfSec,"viewcomments",str(self.viewComments)) cnfParse.set(cnfSec,"viewcomments",str(self.viewComments))
cnfParse.set(cnfSec,"viewsynopsis",str(self.viewSynopsis))
## Path ## Path
cnfSec = "Path" cnfSec = "Path"
@@ -753,11 +758,6 @@ class Config:
self.confChanged = True self.confChanged = True
return self.showRefPanel return self.showRefPanel
def setViewComments(self, checkState):
self.viewComments = checkState
self.confChanged = True
return self.viewComments
def getErrData(self): def getErrData(self):
errMessage = "<br>".join(self.errData) errMessage = "<br>".join(self.errData)
self.hasError = False self.hasError = False
+8 -7
View File
@@ -66,7 +66,7 @@ class ToHtml(Tokenizer):
# Setters # Setters
## ##
def setPreview(self, forPreview, doComments): def setPreview(self, forPreview, doComments, doSynopsis):
"""If we're using this class to generate markdown preview, we """If we're using this class to generate markdown preview, we
need to make a few changes to formatting, which is managed by need to make a few changes to formatting, which is managed by
these flags. these flags.
@@ -75,6 +75,7 @@ class ToHtml(Tokenizer):
self.genMode = self.M_PREVIEW self.genMode = self.M_PREVIEW
self.doKeywords = True self.doKeywords = True
self.doComments = doComments self.doComments = doComments
self.doSynopsis = doSynopsis
self.repDict["\t"] = "&nbsp;"*8 self.repDict["\t"] = "&nbsp;"*8
self._buildRegEx() self._buildRegEx()
return return
@@ -301,18 +302,18 @@ class ToHtml(Tokenizer):
def _formatSynopsis(self, tText): def _formatSynopsis(self, tText):
"""Apply HTML formatting to synopsis. """Apply HTML formatting to synopsis.
""" """
if self.genMode == self.M_EXPORT: if self.genMode == self.M_PREVIEW:
return "<p class='synopsis'><strong>Synopsis: </strong>%s</p>\n" % tText return "<p class='comment'><span class='synopsis'>Synopsis: </span>%s</p>\n" % tText
else: else:
return "<p class='comment'>%s</p>\n" % tText return "<p class='synopsis'><strong>Synopsis: </strong>%s</p>\n" % tText
def _formatComments(self, tText): def _formatComments(self, tText):
"""Apply HTML formatting to comments. """Apply HTML formatting to comments.
""" """
if self.genMode == self.M_EXPORT: if self.genMode == self.M_PREVIEW:
return "<p class='comment'><strong>Comment: </strong>%s</p>\n" % tText
else:
return "<p class='comment'>%s</p>\n" % tText return "<p class='comment'>%s</p>\n" % tText
else:
return "<p class='comment'><strong>Comment: </strong>%s</p>\n" % tText
def _formatKeywords(self, tText): def _formatKeywords(self, tText):
"""Apply HTML formatting to keywords. """Apply HTML formatting to keywords.
+8 -1
View File
@@ -136,7 +136,7 @@ class GuiDocViewer(QTextBrowser):
logger.debug("Generating preview for item %s" % tHandle) logger.debug("Generating preview for item %s" % tHandle)
sPos = self.verticalScrollBar().value() sPos = self.verticalScrollBar().value()
aDoc = ToHtml(self.theProject, self.theParent) aDoc = ToHtml(self.theProject, self.theParent)
aDoc.setPreview(True, self.mainConf.viewComments) aDoc.setPreview(True, self.mainConf.viewComments, self.mainConf.viewSynopsis)
aDoc.setLinkHeaders(True) aDoc.setLinkHeaders(True)
# Be extra careful here to prevent crashes when first opening a # Be extra careful here to prevent crashes when first opening a
@@ -366,6 +366,10 @@ class GuiDocViewer(QTextBrowser):
" margin-left: 1em;" " margin-left: 1em;"
" margin-right: 1em;" " margin-right: 1em;"
"}}\n" "}}\n"
".synopsis {{"
" color: rgb({mColR},{mColG},{mColB});"
" font-wright: bold;"
"}}\n"
).format( ).format(
textSize = self.mainConf.textSize, textSize = self.mainConf.textSize,
preSize = self.mainConf.textSize*0.9, preSize = self.mainConf.textSize*0.9,
@@ -387,6 +391,9 @@ class GuiDocViewer(QTextBrowser):
kColR = self.theTheme.colKey[0], kColR = self.theTheme.colKey[0],
kColG = self.theTheme.colKey[1], kColG = self.theTheme.colKey[1],
kColB = self.theTheme.colKey[2], kColB = self.theTheme.colKey[2],
mColR = self.theTheme.colMod[0],
mColG = self.theTheme.colMod[1],
mColB = self.theTheme.colMod[2],
) )
self.qDocument.setDefaultStyleSheet(styleSheet) self.qDocument.setDefaultStyleSheet(styleSheet)
-13
View File
@@ -114,11 +114,6 @@ class GuiMainMenu(QMenuBar):
self.theProject.setAutoOutline(theMode) self.theProject.setAutoOutline(theMode)
return True return True
def _toggleViewComments(self):
self.mainConf.setViewComments(self.aViewDocComments.isChecked())
self.theParent.docViewer.reloadText()
return True
def _showAbout(self): def _showAbout(self):
"""Show the about dialog. """Show the about dialog.
""" """
@@ -314,14 +309,6 @@ class GuiMainMenu(QMenuBar):
self.aCloseView.triggered.connect(self.theParent.closeDocViewer) self.aCloseView.triggered.connect(self.theParent.closeDocViewer)
self.docuMenu.addAction(self.aCloseView) 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 # Document > Separator
self.docuMenu.addSeparator() self.docuMenu.addSeparator()
+25 -1
View File
@@ -62,7 +62,7 @@ class GuiPreferences(PagedDialog):
self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent) self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent)
self.addTab(self.tabGeneral, "General") self.addTab(self.tabGeneral, "General")
self.addTab(self.tabLayout, "Layout") self.addTab(self.tabLayout, "Text Layout")
self.addTab(self.tabEditing, "Editor") self.addTab(self.tabEditing, "Editor")
self.addTab(self.tabAutoRep, "Auto-Replace") self.addTab(self.tabAutoRep, "Auto-Replace")
@@ -506,6 +506,26 @@ class GuiConfigEditLayoutTab(QWidget):
self.showLineEndings 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 return
def saveValues(self): def saveValues(self):
@@ -523,6 +543,8 @@ class GuiConfigEditLayoutTab(QWidget):
tabWidth = self.tabWidth.value() tabWidth = self.tabWidth.value()
showTabsNSpaces = self.showTabsNSpaces.isChecked() showTabsNSpaces = self.showTabsNSpaces.isChecked()
showLineEndings = self.showLineEndings.isChecked() showLineEndings = self.showLineEndings.isChecked()
viewComments = self.viewComments.isChecked()
viewSynopsis = self.viewSynopsis.isChecked()
self.mainConf.textFont = textFont self.mainConf.textFont = textFont
self.mainConf.textSize = textSize self.mainConf.textSize = textSize
@@ -534,6 +556,8 @@ class GuiConfigEditLayoutTab(QWidget):
self.mainConf.tabWidth = tabWidth self.mainConf.tabWidth = tabWidth
self.mainConf.showTabsNSpaces = showTabsNSpaces self.mainConf.showTabsNSpaces = showTabsNSpaces
self.mainConf.showLineEndings = showLineEndings self.mainConf.showLineEndings = showLineEndings
self.mainConf.viewComments = viewComments
self.mainConf.viewSynopsis = viewSynopsis
self.mainConf.confChanged = True self.mainConf.confChanged = True
+2 -1
View File
@@ -1,5 +1,5 @@
[Main] [Main]
timestamp = 2020-06-09 23:05:17 timestamp = 2020-06-13 22:59:36
theme = default theme = default
syntax = default_light syntax = default_light
icons = typicons_colour_light icons = typicons_colour_light
@@ -54,6 +54,7 @@ askbeforebackup = True
[State] [State]
showrefpanel = True showrefpanel = True
viewcomments = True viewcomments = True
viewsynopsis = True
[Path] [Path]
lastpath = lastpath =
+3 -2
View File
@@ -70,6 +70,7 @@ def testConfigSetTreeColWidths(nwTemp,nwRef):
assert theConf.setTreeColWidths([0, 0, 0]) assert theConf.setTreeColWidths([0, 0, 0])
assert theConf.confChanged assert theConf.confChanged
assert theConf.setTreeColWidths([120, 30, 50]) assert theConf.setTreeColWidths([120, 30, 50])
assert theConf.setProjColWidths([140, 55, 140])
assert theConf.saveConfig() assert theConf.saveConfig()
assert cmpFiles(tmpConf, refConf, [2]) assert cmpFiles(tmpConf, refConf, [2])
assert not theConf.confChanged assert not theConf.confChanged
@@ -82,6 +83,8 @@ def testConfigSetPanePos(nwTemp,nwRef):
assert theConf.confChanged assert theConf.confChanged
assert theConf.setMainPanePos([300, 800]) assert theConf.setMainPanePos([300, 800])
assert theConf.setDocPanePos([400, 400]) assert theConf.setDocPanePos([400, 400])
assert theConf.setViewPanePos([500, 150])
assert theConf.setOutlinePanePos([500, 150])
assert theConf.saveConfig() assert theConf.saveConfig()
assert cmpFiles(tmpConf, refConf, [2]) assert cmpFiles(tmpConf, refConf, [2])
assert not theConf.confChanged assert not theConf.confChanged
@@ -92,8 +95,6 @@ def testConfigFlags(nwTemp,nwRef):
refConf = path.join(nwRef, "novelwriter.conf") refConf = path.join(nwRef, "novelwriter.conf")
assert not theConf.setShowRefPanel(False) assert not theConf.setShowRefPanel(False)
assert theConf.setShowRefPanel(True) assert theConf.setShowRefPanel(True)
assert not theConf.setViewComments(False)
assert theConf.setViewComments(True)
assert theConf.confChanged assert theConf.confChanged
assert theConf.saveConfig() assert theConf.saveConfig()
assert cmpFiles(tmpConf, refConf, [2]) assert cmpFiles(tmpConf, refConf, [2])