Fix merge conflicts
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
# novelWriter ChangeLog
|
||||
|
||||
## Version 0.4.2 [2019-11-17]
|
||||
|
||||
**User Interface**
|
||||
|
||||
* Distraction free mode now also hides the menu bar, but all keyboard shortcuts used for editing remain active. The rest are disabled. PR #142.
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
* Fixed various issues with spell checking highlighting. The highlighting and the editor didn't always agree on what words were spelled wrong. PR #141.
|
||||
* The status bar now shows what spell checking language is actually loaded. Previously, it just showed the language selected in the settings. That was a bit misleading as the available dictionaries can change due to the change in installed dictionary on the system. PR #145.
|
||||
|
||||
## Version 0.4.1 [2019-11-10]
|
||||
|
||||
**Features**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[](https://codecov.io/gh/vkbo/novelWriter)
|
||||
[](https://novelwriter.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
novelWriter is a markdown-like text editor designed fro writing novels and larger projects of many smaller plain text documents.
|
||||
novelWriter is a markdown-like text editor designed for writing novels and larger projects of many smaller plain text documents.
|
||||
|
||||
The documentation is available here: [novelwriter.readthedocs.io](https://novelwriter.readthedocs.io/).
|
||||
|
||||
@@ -20,6 +20,34 @@ If you do use it for real projects, please run backups frequently to avoid data
|
||||
There is a built in backup feature that can pack the entire project into a zip file on close.
|
||||
Please check the documentation for further details.
|
||||
|
||||
## Markdown Flavour
|
||||
|
||||
novelWriter is **not** a full-feature Markdown editor.
|
||||
It allows for a minimal set of formatting needed for writing text documents for novels.
|
||||
These are currently limited to:
|
||||
|
||||
* Headings level 1 to 4 using the `#` syntax only.
|
||||
* Bold, italic and underline text.
|
||||
* Hard line breaks using two or more spaces at the end of a line.
|
||||
|
||||
That is it.
|
||||
Features not supported in the editor are also not exported when using the export tool.
|
||||
|
||||
In addition, novelWriter adds the following, which is otherwise not supported by Markdown:
|
||||
|
||||
* A line starting with `%` is treated as a comment and not rendered on exports unless requested.
|
||||
Comments do not count towards the word count.
|
||||
* A set of meta data keyword/value sets starting with the character `@`.
|
||||
This is used for tagging and inter-linking documents.
|
||||
* Non-breaking spaces are supported as long as your system is using at least Qt 5.9.
|
||||
For earlier version, non-breaking spaces are converted to normal spaces when saving the document.
|
||||
This is done by the Qt library.
|
||||
* Tabs may be rendered, depending on export format.
|
||||
|
||||
The core export format that should render properly all supported features is the HTML export.
|
||||
This format also forms the basis of conversion to Office type document formats with Pandoc.
|
||||
Note that Pandoc itself strips some formatting from the document during conversion, so the final result may be different than expected.
|
||||
|
||||
## Implementation
|
||||
|
||||
The application is written in Python3 using Qt5 via PyQt5.
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ copyright = "2018-2019, Veronica Berglyd Olsen"
|
||||
author = "Veronica Berglyd Olsen"
|
||||
|
||||
# The short X.Y version
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = "0.4.1"
|
||||
release = "0.4.2"
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@ __package__ = "novelWriter"
|
||||
__author__ = "Veronica Berglyd Olsen"
|
||||
__copyright__ = "Copyright 2018–2019, Veronica Berglyd Olsen"
|
||||
__license__ = "GPLv3"
|
||||
__version__ = "0.4.1"
|
||||
__date__ = "2019-11-10"
|
||||
__version__ = "0.4.2"
|
||||
__date__ = "2019-11-17"
|
||||
__maintainer__ = "Veronica Berglyd Olsen"
|
||||
__email__ = "code@vkbo.net"
|
||||
__status__ = "Development"
|
||||
|
||||
@@ -93,6 +93,7 @@ class Config:
|
||||
self.wordCountTimer = 5.0
|
||||
self.showTabsNSpaces = False
|
||||
self.showLineEndings = False
|
||||
self.bigDocLimit = 800
|
||||
|
||||
self.fmtApostrophe = nwUnicode.U_RSQUO
|
||||
self.fmtSingleQuotes = [nwUnicode.U_LSQUO,nwUnicode.U_RSQUO]
|
||||
@@ -322,6 +323,9 @@ class Config:
|
||||
self.showLineEndings = self._parseLine(
|
||||
cnfParse, cnfSec, "showlineendings", self.CNF_BOOL, self.showLineEndings
|
||||
)
|
||||
self.bigDocLimit = self._parseLine(
|
||||
cnfParse, cnfSec, "bigdoclimit", self.CNF_INT, self.bigDocLimit
|
||||
)
|
||||
|
||||
## Backup
|
||||
cnfSec = "Backup"
|
||||
@@ -412,6 +416,7 @@ class Config:
|
||||
cnfParse.set(cnfSec,"spellcheck", str(self.spellLanguage))
|
||||
cnfParse.set(cnfSec,"showtabsnspaces", str(self.showTabsNSpaces))
|
||||
cnfParse.set(cnfSec,"showlineendings", str(self.showLineEndings))
|
||||
cnfParse.set(cnfSec,"bigdoclimit", str(self.bigDocLimit))
|
||||
|
||||
## Backup
|
||||
cnfSec = "Backup"
|
||||
|
||||
@@ -85,7 +85,8 @@ class ToMarkdown(Tokenizer):
|
||||
# indicating a new paragraph.
|
||||
if tType == self.T_EMPTY:
|
||||
if len(thisPar) > 0:
|
||||
self.theResult += "%s\n\n" % " ".join(thisPar)
|
||||
tTemp = "\n".join(thisPar)
|
||||
self.theResult += "%s\n\n" % tTemp.rstrip()
|
||||
thisPar = []
|
||||
|
||||
elif tType == self.T_HEAD1:
|
||||
@@ -104,7 +105,7 @@ class ToMarkdown(Tokenizer):
|
||||
self.theResult += "%s\n\n" % tText
|
||||
|
||||
elif tType == self.T_SKIP:
|
||||
self.theResult += "\n\n\n\n"
|
||||
self.theResult += "\n\n\n"
|
||||
|
||||
elif tType == self.T_TEXT:
|
||||
thisPar.append(tText)
|
||||
|
||||
@@ -122,8 +122,8 @@ class ToText(Tokenizer):
|
||||
tText = self._centreText(tText,self.wordWrap)
|
||||
self.theResult += "%s\n\n" % tText
|
||||
|
||||
elif tType == self.T_SEP:
|
||||
self.theResult += "\n\n\n\n"
|
||||
elif tType == self.T_SKIP:
|
||||
self.theResult += "\n\n\n"
|
||||
|
||||
elif tType == self.T_TEXT:
|
||||
thisPar.append(tText)
|
||||
|
||||
@@ -44,7 +44,6 @@ class GuiConfigEditor(QDialog):
|
||||
self.setWindowTitle("Preferences")
|
||||
self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64))
|
||||
|
||||
self.theProject.countStatus()
|
||||
self.tabMain = GuiConfigEditGeneral(self.theParent)
|
||||
self.tabEditor = GuiConfigEditEditor(self.theParent)
|
||||
|
||||
@@ -174,11 +173,24 @@ class GuiConfigEditGeneral(QWidget):
|
||||
self.spellToolList.setCurrentIndex(toolIdx)
|
||||
self._doUpdateSpellTool(0)
|
||||
|
||||
self.spellLangForm.addWidget(QLabel("Provider"), 0, 0)
|
||||
self.spellLangForm.addWidget(self.spellToolList, 0, 1)
|
||||
self.spellLangForm.addWidget(QLabel("Language"), 1, 0)
|
||||
self.spellLangForm.addWidget(self.spellLangList, 1, 1)
|
||||
self.spellLangForm.setColumnStretch(2, 1)
|
||||
self.spellBigDoc = QSpinBox(self)
|
||||
self.spellBigDoc.setMinimum(10)
|
||||
self.spellBigDoc.setMaximum(10000)
|
||||
self.spellBigDoc.setSingleStep(10)
|
||||
self.spellBigDoc.setToolTip((
|
||||
"Disable spell checking when loading large documents. "
|
||||
"Spell checking will only run on paragraphs you edit."
|
||||
))
|
||||
self.spellBigDoc.setValue(self.mainConf.bigDocLimit)
|
||||
|
||||
self.spellLangForm.addWidget(QLabel("Provider"), 0, 0)
|
||||
self.spellLangForm.addWidget(self.spellToolList, 0, 1, 1, 3)
|
||||
self.spellLangForm.addWidget(QLabel("Language"), 1, 0)
|
||||
self.spellLangForm.addWidget(self.spellLangList, 1, 1, 1, 3)
|
||||
self.spellLangForm.addWidget(QLabel("Size limit"), 2, 0)
|
||||
self.spellLangForm.addWidget(self.spellBigDoc, 2, 1)
|
||||
self.spellLangForm.addWidget(QLabel("kb"), 2, 2)
|
||||
self.spellLangForm.setColumnStretch(4, 1)
|
||||
|
||||
# AutoSave
|
||||
self.autoSave = QGroupBox("Automatic Save", self)
|
||||
@@ -252,6 +264,7 @@ class GuiConfigEditGeneral(QWidget):
|
||||
guiDark = self.guiDarkIcons.isChecked()
|
||||
spellTool = self.spellToolList.currentData()
|
||||
spellLanguage = self.spellLangList.currentData()
|
||||
bigDocLimit = self.spellBigDoc.value()
|
||||
autoSaveDoc = self.autoSaveDoc.value()
|
||||
autoSaveProj = self.autoSaveProj.value()
|
||||
backupPath = self.projBackupPath.text()
|
||||
@@ -266,6 +279,7 @@ class GuiConfigEditGeneral(QWidget):
|
||||
self.mainConf.guiDark = guiDark
|
||||
self.mainConf.spellTool = spellTool
|
||||
self.mainConf.spellLanguage = spellLanguage
|
||||
self.mainConf.bigDocLimit = bigDocLimit
|
||||
self.mainConf.autoSaveDoc = autoSaveDoc
|
||||
self.mainConf.autoSaveProj = autoSaveProj
|
||||
self.mainConf.backupPath = backupPath
|
||||
@@ -541,6 +555,7 @@ class GuiConfigEditEditor(QWidget):
|
||||
self.outerBox.addWidget(self.quoteStyle, 2, 1, 2, 1)
|
||||
self.outerBox.addWidget(self.showGuides, 4, 1)
|
||||
self.outerBox.setColumnStretch(2, 1)
|
||||
self.outerBox.setRowStretch(5, 1)
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
return
|
||||
|
||||
@@ -50,7 +50,6 @@ class GuiExport(QDialog):
|
||||
|
||||
self.guiDeco = self.theParent.theTheme.loadDecoration("export",(64,64))
|
||||
|
||||
self.theProject.countStatus()
|
||||
self.tabMain = GuiExportMain(self.theParent, self.theProject, self.optState)
|
||||
self.tabPandoc = GuiExportPandoc(self.theParent, self.theProject, self.optState)
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ class GuiDocEditor(QTextEdit):
|
||||
self.wordCount = 0
|
||||
self.paraCount = 0
|
||||
self.lastEdit = 0
|
||||
self.bigDoc = False
|
||||
self.nonWord = "\"'"
|
||||
|
||||
# Typography
|
||||
@@ -114,17 +115,22 @@ class GuiDocEditor(QTextEdit):
|
||||
return
|
||||
|
||||
def clearEditor(self):
|
||||
"""Clear the current document and reset all document related
|
||||
flags and counters.
|
||||
"""
|
||||
|
||||
self.nwDocument.clearDocument()
|
||||
self.setReadOnly(True)
|
||||
self.clear()
|
||||
self.wcTimer.stop()
|
||||
|
||||
self.theHandle = None
|
||||
self.charCount = 0
|
||||
self.wordCount = 0
|
||||
self.paraCount = 0
|
||||
self.lastEdit = 0
|
||||
self.theHandle = None
|
||||
self.charCount = 0
|
||||
self.wordCount = 0
|
||||
self.paraCount = 0
|
||||
self.lastEdit = 0
|
||||
self.bigDoc = False
|
||||
|
||||
self.hasSelection = False
|
||||
|
||||
self.setDocumentChanged(False)
|
||||
@@ -214,7 +220,19 @@ class GuiDocEditor(QTextEdit):
|
||||
return False
|
||||
|
||||
self.hLight.setHandle(tHandle)
|
||||
|
||||
# Check that the document is not too big for full, initial spell
|
||||
# checking. If it is too big, we switch to only check as we type
|
||||
self._checkDocSize(len(theDoc))
|
||||
spTemp = self.hLight.spellCheck
|
||||
if self.bigDoc:
|
||||
self.hLight.spellCheck = False
|
||||
|
||||
bfTime = time()
|
||||
self.setPlainText(theDoc)
|
||||
afTime = time()
|
||||
logger.debug("Document highlighted in %.3f milliseconds" % (1000*(afTime-bfTime)))
|
||||
|
||||
self.setCursorPosition(self.nwDocument.theItem.cursorPos)
|
||||
self.lastEdit = time()
|
||||
self._runCounter()
|
||||
@@ -227,8 +245,18 @@ class GuiDocEditor(QTextEdit):
|
||||
else:
|
||||
self.theParent.noticeBar.showNote("This document is read only.")
|
||||
|
||||
self.hLight.spellCheck = spTemp
|
||||
|
||||
return True
|
||||
|
||||
def replaceText(self, theText):
|
||||
"""Replaces the text of the current document with the provided
|
||||
text. This also clears undo history.
|
||||
"""
|
||||
self.setPlainText(theText)
|
||||
self.setDocumentChanged(True)
|
||||
return
|
||||
|
||||
def saveText(self):
|
||||
|
||||
if self.nwDocument.theItem is None:
|
||||
@@ -250,7 +278,7 @@ class GuiDocEditor(QTextEdit):
|
||||
|
||||
def updateDocMargins(self):
|
||||
"""Automatically adjust the margins so the text is centred, but
|
||||
only if Config.textFixedW is set to True.
|
||||
only if Config.textFixedW is enabled or we're in Zen mode.
|
||||
"""
|
||||
|
||||
if self.mainConf.textFixedW or self.theParent.isZenMode:
|
||||
@@ -273,7 +301,15 @@ class GuiDocEditor(QTextEdit):
|
||||
docFormat = self.qDocument.rootFrame().frameFormat()
|
||||
docFormat.setLeftMargin(tM)
|
||||
docFormat.setRightMargin(tM)
|
||||
|
||||
# Updating root frame triggers a QTextDocument->contentsChange
|
||||
# signal, which we do not want as it re-runs the syntax
|
||||
# highlighter and spell checker, so we block it briefly.
|
||||
# We then emit a signal that does not trigger re-highlighting.
|
||||
self.qDocument.blockSignals(True)
|
||||
self.qDocument.rootFrame().setFrameFormat(docFormat)
|
||||
self.qDocument.blockSignals(False)
|
||||
self.qDocument.contentsChange.emit(0,0,0)
|
||||
|
||||
return
|
||||
|
||||
@@ -339,18 +375,26 @@ class GuiDocEditor(QTextEdit):
|
||||
self.theParent.mainMenu.setSpellCheck(theMode)
|
||||
self.theProject.setSpellCheck(theMode)
|
||||
self.hLight.setSpellCheck(theMode)
|
||||
self.hLight.rehighlight()
|
||||
self.reHighlightDocument()
|
||||
|
||||
logger.verbose("Spell check is set to %s" % str(theMode))
|
||||
|
||||
return True
|
||||
|
||||
def updateSpellCheck(self):
|
||||
def reHighlightDocument(self):
|
||||
"""Rerun the highlighter to update spell checking status of the
|
||||
currently loaded text.
|
||||
currently loaded text. The fastest way to do this, at least as
|
||||
of Qt 5.13, is to clear the text and put it back.
|
||||
"""
|
||||
|
||||
if self.spellCheck:
|
||||
self.hLight.rehighlight()
|
||||
theText = self.getText()
|
||||
self.clear()
|
||||
bfTime = time()
|
||||
self.setPlainText(theText)
|
||||
afTime = time()
|
||||
logger.debug("Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime)))
|
||||
|
||||
return True
|
||||
|
||||
##
|
||||
@@ -582,6 +626,9 @@ class GuiDocEditor(QTextEdit):
|
||||
return
|
||||
|
||||
def _docChange(self, thePos, charsRemoved, charsAdded):
|
||||
"""Triggered by QTextDocument->contentsChanged. This also
|
||||
triggers the syntax highlighter.
|
||||
"""
|
||||
self.lastEdit = time()
|
||||
if not self.docChanged:
|
||||
self.setDocumentChanged(True)
|
||||
@@ -673,9 +720,24 @@ class GuiDocEditor(QTextEdit):
|
||||
self.theParent.statusBar.setCounts(self.charCount,self.wordCount,self.paraCount)
|
||||
self.theParent.treeView.propagateCount(tHandle, self.wordCount)
|
||||
self.theParent.treeView.projectWordCount()
|
||||
self._checkDocSize(self.charCount)
|
||||
|
||||
return
|
||||
|
||||
def _checkDocSize(self, theSize):
|
||||
"""Check if document size crosses the big document limit set in
|
||||
config. If so, we will set the big document flag to True.
|
||||
"""
|
||||
if theSize > self.mainConf.bigDocLimit*1000:
|
||||
logger.info(
|
||||
"The document size is %d > %d, big doc mode is enabled" % (
|
||||
theSize, self.mainConf.bigDocLimit*1000
|
||||
))
|
||||
self.bigDoc = True
|
||||
else:
|
||||
self.bigDoc = False
|
||||
return
|
||||
|
||||
def _wrapSelection(self, tBefore, tAfter):
|
||||
"""Wraps the selected text in whatever is in tBefore and tAfter.
|
||||
If there is no selection, the autoSelect setting decides the
|
||||
|
||||
+1
-1
@@ -608,7 +608,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aReRunSpell = QAction("Re-Run Spell Check", self)
|
||||
self.aReRunSpell.setStatusTip("Run the spell checker on current document")
|
||||
self.aReRunSpell.setShortcut("F7")
|
||||
self.aReRunSpell.triggered.connect(self.theParent.docEditor.updateSpellCheck)
|
||||
self.aReRunSpell.triggered.connect(self.theParent.docEditor.reHighlightDocument)
|
||||
self.toolsMenu.addAction(self.aReRunSpell)
|
||||
|
||||
# Tools > Separator
|
||||
|
||||
@@ -101,54 +101,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
"value" : self._makeFormat(self.colVal),
|
||||
}
|
||||
|
||||
# Headers
|
||||
self.hRules = []
|
||||
self.hRules.append((
|
||||
r"^(#{1}) (.*)[^\n]", {
|
||||
0 : self.hStyles["header1"],
|
||||
1 : self.hStyles["header1h"],
|
||||
}
|
||||
))
|
||||
self.hRules.append((
|
||||
r"^(#{2}) (.*)[^\n]", {
|
||||
0 : self.hStyles["header2"],
|
||||
1 : self.hStyles["header2h"],
|
||||
}
|
||||
))
|
||||
self.hRules.append((
|
||||
r"^(#{3}) (.*)[^\n]", {
|
||||
0 : self.hStyles["header3"],
|
||||
1 : self.hStyles["header3h"],
|
||||
}
|
||||
))
|
||||
self.hRules.append((
|
||||
r"^(#{4}) (.*)[^\n]", {
|
||||
0 : self.hStyles["header4"],
|
||||
1 : self.hStyles["header4h"],
|
||||
}
|
||||
))
|
||||
|
||||
# Keyword/Value
|
||||
# self.hRules.append((
|
||||
# r"^(@.+?)\s*:\s*(.+?)$", {
|
||||
# 1 : self.hStyles["keyword"],
|
||||
# 2 : self.hStyles["value"],
|
||||
# }
|
||||
# ))
|
||||
|
||||
# Comments
|
||||
self.hRules.append((
|
||||
r"^%.*$", {
|
||||
0 : self.hStyles["hidden"],
|
||||
}
|
||||
))
|
||||
self.hRules.append((
|
||||
r"^(%)(synopsis:\s+)(.*)$", {
|
||||
1 : self.hStyles["hidden"],
|
||||
2 : self.hStyles["keyword"],
|
||||
3 : self.hStyles["hidden"],
|
||||
}
|
||||
))
|
||||
|
||||
# Trailing Spaces, 2+
|
||||
self.hRules.append((
|
||||
@@ -248,12 +201,16 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
##
|
||||
|
||||
def highlightBlock(self, theText):
|
||||
"""Highlight a single block. Prefer to check first character for
|
||||
all formats that are defined by their initial characters. This
|
||||
is significantly faster than running the regex checks we use for
|
||||
text paragraphs.
|
||||
"""
|
||||
|
||||
if self.theHandle is None:
|
||||
if self.theHandle is None or not theText:
|
||||
return
|
||||
|
||||
if theText.startswith("@"):
|
||||
# Highlighting of keywords and commands
|
||||
if theText.startswith("@"): # Keywords and commands
|
||||
tItem = self.theParent.theProject.getItem(self.theHandle)
|
||||
isValid, theBits, thePos = self.theIndex.scanThis(theText)
|
||||
isGood = self.theIndex.checkThese(theBits, tItem)
|
||||
@@ -272,11 +229,30 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
kwFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||
self.setFormat(xPos, xLen, kwFmt)
|
||||
|
||||
# We're done, no need to continue
|
||||
# We never want to run the spell checker on keyword/values,
|
||||
# so we force a return here
|
||||
return
|
||||
|
||||
else:
|
||||
# For other text, just use our regex rules
|
||||
elif theText.startswith("# "): # Header 1
|
||||
self.setFormat(0, 1, self.hStyles["header1h"])
|
||||
self.setFormat(1, len(theText), self.hStyles["header1"])
|
||||
|
||||
elif theText.startswith("## "): # Header 2
|
||||
self.setFormat(0, 2, self.hStyles["header2h"])
|
||||
self.setFormat(2, len(theText), self.hStyles["header2"])
|
||||
|
||||
elif theText.startswith("### "): # Header 3
|
||||
self.setFormat(0, 3, self.hStyles["header3h"])
|
||||
self.setFormat(3, len(theText), self.hStyles["header3"])
|
||||
|
||||
elif theText.startswith("#### "): # Header 4
|
||||
self.setFormat(0, 4, self.hStyles["header4h"])
|
||||
self.setFormat(4, len(theText), self.hStyles["header4"])
|
||||
|
||||
elif theText.startswith("%"): # Comments
|
||||
self.setFormat(0, len(theText), self.hStyles["hidden"])
|
||||
|
||||
else: # Text Paragraph
|
||||
for rX, xFmt in self.rxRules:
|
||||
rxItt = rX.globalMatch(theText, 0)
|
||||
while rxItt.hasNext():
|
||||
@@ -310,6 +286,10 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
##
|
||||
|
||||
def _makeFormat(self, fmtCol=None, fmtStyle=None, fmtSize=None):
|
||||
"""Generate a valid character format to be applied to the text
|
||||
that is to be highlighted.
|
||||
"""
|
||||
|
||||
theFormat = QTextCharFormat()
|
||||
|
||||
if fmtCol is not None:
|
||||
|
||||
+8
-3
@@ -107,6 +107,7 @@ class GuiMain(QMainWindow):
|
||||
self.viewPane.setLayout(self.docView)
|
||||
|
||||
self.splitView = QSplitter(Qt.Horizontal)
|
||||
self.splitView.setOpaqueResize(False)
|
||||
self.splitView.addWidget(self.editPane)
|
||||
self.splitView.addWidget(self.viewPane)
|
||||
|
||||
@@ -119,6 +120,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
self.splitMain = QSplitter(Qt.Horizontal)
|
||||
self.splitMain.setContentsMargins(4,4,4,4)
|
||||
self.splitMain.setOpaqueResize(False)
|
||||
self.splitMain.addWidget(self.treePane)
|
||||
self.splitMain.addWidget(self.tabWidget)
|
||||
self.splitMain.setSizes(self.mainConf.mainPanePos)
|
||||
@@ -426,17 +428,20 @@ class GuiMain(QMainWindow):
|
||||
)
|
||||
if inPath:
|
||||
loadFile = inPath[0]
|
||||
self.mainConf.setLastPath(loadFile)
|
||||
else:
|
||||
return False
|
||||
|
||||
if loadFile.strip() == "":
|
||||
return False
|
||||
|
||||
theText = None
|
||||
try:
|
||||
with open(loadFile,mode="rt",encoding="utf8") as inFile:
|
||||
theText = inFile.read()
|
||||
self.mainConf.setLastPath(loadFile)
|
||||
except Exception as e:
|
||||
self.makeAlert(
|
||||
["Could not read file. The file cannot be a binary file.",str(e)],
|
||||
["Could not read file. The file must be an existing text file.",str(e)],
|
||||
nwAlert.ERROR
|
||||
)
|
||||
return False
|
||||
@@ -460,7 +465,7 @@ class GuiMain(QMainWindow):
|
||||
else:
|
||||
return False
|
||||
|
||||
self.docEditor.setText(theText)
|
||||
self.docEditor.replaceText(theText)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -582,6 +582,9 @@ class NWProject():
|
||||
return True
|
||||
|
||||
def countStatus(self):
|
||||
"""Count how many times the various status flags are used in the
|
||||
project tree.
|
||||
"""
|
||||
self.statusItems.resetCounts()
|
||||
self.importItems.resetCounts()
|
||||
for nwItem in self.projTree.values():
|
||||
|
||||
@@ -41,6 +41,8 @@ class NWStatus():
|
||||
return True
|
||||
|
||||
def lookupEntry(self, theLabel):
|
||||
if theLabel is None:
|
||||
return None
|
||||
theLabel = theLabel.strip()
|
||||
if theLabel in self.theMap.keys():
|
||||
return self.theMap[theLabel]
|
||||
|
||||
@@ -6,7 +6,7 @@ with open("README.md", "r") as inFile:
|
||||
|
||||
setuptools.setup(
|
||||
name = "novelWriter",
|
||||
version = "0.4.1",
|
||||
version = "0.4.2",
|
||||
author = "Veronica Berglyd Olsen",
|
||||
author_email = "code@vkbo.net",
|
||||
description = "A markdown-like document editor for writing novels",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Main]
|
||||
timestamp = 2019-11-09 14:38:32
|
||||
timestamp = 2019-11-19 21:49:29
|
||||
theme = default
|
||||
syntax = default_light
|
||||
guidark = False
|
||||
@@ -36,6 +36,7 @@ spelltool = internal
|
||||
spellcheck = en
|
||||
showtabsnspaces = False
|
||||
showlineendings = False
|
||||
bigdoclimit = 800
|
||||
|
||||
[Backup]
|
||||
backuppath =
|
||||
|
||||
Reference in New Issue
Block a user