From 0f67e9b97114645f0c64eed0289869a2f80dbb50 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 20:32:12 +0200 Subject: [PATCH 1/7] Improve the error messages when adding a new file or folder without selecting a location --- nw/gui/doctree.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nw/gui/doctree.py b/nw/gui/doctree.py index 48898952..1d47bcee 100644 --- a/nw/gui/doctree.py +++ b/nw/gui/doctree.py @@ -98,8 +98,16 @@ class GuiDocTree(QTreeWidget): if itemClass is None and pHandle is not None: itemClass = self.theProject.getItem(pHandle).itemClass + if itemClass is None: - self.makeAlert("Failed to find an appropriate item class for item %s" % pHandle, nwAlert.BUG) + if itemType is not None: + if itemType == nwItemType.FILE: + self.makeAlert("Please select a location in the tree to add a document.", nwAlert.ERROR) + return False + elif itemType == nwItemType.FOLDER: + self.makeAlert("Please select a location in the tree to add a folder.", nwAlert.ERROR) + return False + self.makeAlert("Failed to add new item.", nwAlert.BUG) return False logger.verbose("Adding new item of type %s and class %s to handle %s" % ( From 558af9f329c30821a2c071bd737dc914f282f0ca Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:05:33 +0200 Subject: [PATCH 2/7] Added an import file to document feature --- nw/config.py | 8 ++++++++ nw/gui/doceditor.py | 3 +++ nw/gui/itemeditor.py | 2 +- nw/gui/mainmenu.py | 11 ++++++++-- nw/gui/winmain.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/nw/config.py b/nw/config.py index 4e7ecde5..cd8b5c63 100644 --- a/nw/config.py +++ b/nw/config.py @@ -47,6 +47,7 @@ class Config: self.confPath = None self.confFile = None self.homePath = None + self.lastPath = None self.appPath = None self.appRoot = None self.appIcon = None @@ -129,6 +130,7 @@ class Config: self.confFile = self.appHandle+".conf" self.homePath = path.expanduser("~") + self.lastPath = self.homePath self.appPath = path.dirname(__file__) self.appRoot = path.join(self.appPath,path.pardir) self.helpPath = path.join(self.appRoot,"help","en_GB") @@ -212,6 +214,7 @@ class Config: ## Path cnfSec = "Path" + self.lastPath = self._parseLine(cnfParse, cnfSec, "lastpath", self.CNF_STR, self.lastPath) for i in range(10): self.recentList[i] = self._parseLine(cnfParse, cnfSec, "recent%d" % i,self.CNF_STR, self.recentList[i]) @@ -278,6 +281,7 @@ class Config: ## Path cnfSec = "Path" cnfParse.add_section(cnfSec) + cnfParse.set(cnfSec,"lastpath", str(self.lastPath)) for i in range(10): cnfParse.set(cnfSec,"recent%d" % i, str(self.recentList[i])) @@ -312,6 +316,10 @@ class Config: self.confFile = path.basename(newPath) return True + def setLastPath(self, lastPath): + self.lastPath = path.dirname(lastPath) + return True + def setWinSize(self, newWidth, newHeight): if abs(self.winGeometry[0] - newWidth) > 5: self.winGeometry[0] = newWidth diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index a9a319f2..88d2460f 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -289,6 +289,9 @@ class GuiDocEditor(QTextEdit): return False return True + def isEmpty(self): + return self.qDocument.isEmpty() + ## # Document Events and Maintenance ## diff --git a/nw/gui/itemeditor.py b/nw/gui/itemeditor.py index a049aaf2..52019bf9 100644 --- a/nw/gui/itemeditor.py +++ b/nw/gui/itemeditor.py @@ -87,7 +87,7 @@ class GuiItemEditor(QDialog): if itemLayout in self.validLayouts: self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout],itemLayout) - self.mainForm.addRow("Name", self.editName) + self.mainForm.addRow("Label", self.editName) self.mainForm.addRow("Status", self.editStatus) self.mainForm.addRow("Layout", self.editLayout) diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 94c6b317..cf67d4ce 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -312,8 +312,15 @@ class GuiMainMenu(QMenuBar): menuItem.triggered.connect(self.theParent.closeDocViewer) self.docuMenu.addAction(menuItem) - # # Document > Separator - # self.docuMenu.addSeparator() + # Document > Separator + self.docuMenu.addSeparator() + + # Document > Close Preview + menuItem = QAction("Import from File", self) + menuItem.setStatusTip("Import document from a text or markdown file") + menuItem.setShortcut("Ctrl+Shift+I") + menuItem.triggered.connect(self.theParent.importDocument) + self.docuMenu.addAction(menuItem) # # Document > Split # menuItem = QAction("Split Document", self) diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py index 5e2f4b64..866b5070 100644 --- a/nw/gui/winmain.py +++ b/nw/gui/winmain.py @@ -366,6 +366,54 @@ class GuiMain(QMainWindow): return True + def importDocument(self): + + lastPath = self.mainConf.lastPath + + extFilter = [ + "Text files (*.txt)", + "Markdown files (*.md)", + "All files (*.*)", + ] + dlgOpt = QFileDialog.Options() + dlgOpt |= QFileDialog.DontUseNativeDialog + inPath = QFileDialog.getOpenFileName( + self,"Import File",lastPath,options=dlgOpt,filter=";;".join(extFilter) + ) + if inPath: + loadFile = inPath[0] + self.mainConf.setLastPath(loadFile) + else: + return False + + theText = None + try: + with open(loadFile,mode="r") as inFile: + theText = inFile.read() + except Exception as e: + self.makeAlert(["Could not read file. The file cannot be a binary file.",str(e)], nwAlert.ERROR) + return False + + if self.docEditor.theHandle is None: + self.makeAlert(["Please open a document to import the text file into."], nwAlert.ERROR) + return False + + if not self.docEditor.isEmpty(): + if self.mainConf.showGUI: + msgBox = QMessageBox() + msgRes = msgBox.question( + self, "Import Document", + "Importing the file will overwrite the current content of the document. Do you want to proceed?" + ) + if msgRes != QMessageBox.Yes: + return False + else: + return False + + self.docEditor.setText(theText) + + return True + ## # Tree Item Actions ## From e4b36a864611af53e7c2c62ca2cffbd5f05e05a5 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:13:51 +0200 Subject: [PATCH 3/7] Make the import file explicitly mode='rt' --- nw/gui/winmain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py index 866b5070..8a5d28ff 100644 --- a/nw/gui/winmain.py +++ b/nw/gui/winmain.py @@ -388,7 +388,7 @@ class GuiMain(QMainWindow): theText = None try: - with open(loadFile,mode="r") as inFile: + with open(loadFile,mode="rt") as inFile: theText = inFile.read() except Exception as e: self.makeAlert(["Could not read file. The file cannot be a binary file.",str(e)], nwAlert.ERROR) From 3419839295ebb862c2980b5a29231855004a5ee5 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:21:29 +0200 Subject: [PATCH 4/7] Fix a corner case nonetype exit --- nw/gui/doctree.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nw/gui/doctree.py b/nw/gui/doctree.py index 1d47bcee..600e8fee 100644 --- a/nw/gui/doctree.py +++ b/nw/gui/doctree.py @@ -426,9 +426,10 @@ class GuiDocTree(QTreeWidget): return def _cleanOrphanedRoot(self): - if self.orphRoot.childCount() == 0: - self.takeTopLevelItem(self.indexOfTopLevelItem(self.orphRoot)) - self.orphRoot = None + if self.orphRoot is not None: + if self.orphRoot.childCount() == 0: + self.takeTopLevelItem(self.indexOfTopLevelItem(self.orphRoot)) + self.orphRoot = None return def _updateItemParent(self, tHandle): From 68ddba17682ead983891d6ab7155f57e1087ed29 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:21:49 +0200 Subject: [PATCH 5/7] Added an unnumbered chapter to the sample project --- .../sampleNovel/data_b/a8a28a246524_main.nwd | 16 ++++++++++++ sample/sampleNovel/nwProject.nwx | 26 ++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 sample/sampleNovel/data_b/a8a28a246524_main.nwd diff --git a/sample/sampleNovel/data_b/a8a28a246524_main.nwd b/sample/sampleNovel/data_b/a8a28a246524_main.nwd new file mode 100644 index 00000000..81b90cc6 --- /dev/null +++ b/sample/sampleNovel/data_b/a8a28a246524_main.nwd @@ -0,0 +1,16 @@ +## Interlude + +I am the very model of a modern Major-General +I've information vegetable, animal, and mineral +I know the kings of England, and I quote the fights historical +From Marathon to Waterloo, in order categorical + +I'm very well acquainted, too, with matters mathematical +I understand equations, both the simple and quadratical +About binomial theorem I'm teeming with a lot o’ news +With many cheerful facts about the square of the hypotenuse + +With many cheerful facts about the square of the hypotenuse +With many cheerful facts about the square of the hypotenuse +With many cheerful facts about the square of the hypotepotenuse + diff --git a/sample/sampleNovel/nwProject.nwx b/sample/sampleNovel/nwProject.nwx index e6689e70..58d2d21a 100644 --- a/sample/sampleNovel/nwProject.nwx +++ b/sample/sampleNovel/nwProject.nwx @@ -1,5 +1,5 @@ - + Sample Project Sample Project @@ -9,9 +9,9 @@ True - 636b6aa9b697b + ba8a28a246524 636b6aa9b697b - 758 + 859 B E @@ -33,7 +33,7 @@ Main - + Novel ROOT @@ -96,7 +96,19 @@ 2 448 - + + Interlude + FILE + NOVEL + Finished + False + UNNUMBERED + 614 + 101 + 3 + 633 + + A Note on Ipsums FILE NOVEL @@ -108,7 +120,7 @@ 5 0 - + Chapter Two FILE NOVEL @@ -120,7 +132,7 @@ 0 76 - + We Found John! FILE NOVEL From 9186289c1bfcdf0531e80c175f237e2234599463 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:22:35 +0200 Subject: [PATCH 6/7] Changed the spelling of 'unnumbered' --- nw/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nw/constants.py b/nw/constants.py index 53078be0..798984a9 100644 --- a/nw/constants.py +++ b/nw/constants.py @@ -61,7 +61,7 @@ class nwLabels(): nwItemLayout.BOOK : "Book", nwItemLayout.PAGE : "Plain Page", nwItemLayout.PARTITION : "Partition", - nwItemLayout.UNNUMBERED : "Un-Numbered", + nwItemLayout.UNNUMBERED : "Unnumbered", nwItemLayout.CHAPTER : "Chapter", nwItemLayout.SCENE : "Scene", nwItemLayout.NOTE : "Note", From dc12d518c0614ffeaa192fdfcd2d2853c9820416 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:34:25 +0200 Subject: [PATCH 7/7] Fixed test --- nw/config.py | 5 ++++- tests/reference/novelwriter.conf | 1 + tests/test_config.py | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/nw/config.py b/nw/config.py index cd8b5c63..722f4141 100644 --- a/nw/config.py +++ b/nw/config.py @@ -317,7 +317,10 @@ class Config: return True def setLastPath(self, lastPath): - self.lastPath = path.dirname(lastPath) + if lastPath is None or lastPath == "": + self.lastPath = "" + else: + self.lastPath = path.dirname(lastPath) return True def setWinSize(self, newWidth, newHeight): diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index 7ea29925..90c48661 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -37,6 +37,7 @@ backuponclose = False askbeforebackup = True [Path] +lastpath = recent0 = recent1 = recent2 = diff --git a/tests/test_config.py b/tests/test_config.py index 12fc5c18..4c4c2523 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -14,6 +14,8 @@ def testConfigInit(nwTemp,nwRef): tmpConf = path.join(nwTemp,"novelwriter.conf") refConf = path.join(nwRef, "novelwriter.conf") assert theConf.initConfig(nwTemp) + assert theConf.setLastPath("") + assert theConf.saveConfig() assert cmpFiles(tmpConf, refConf, [2]) assert not theConf.confChanged