Populate the add button menu in the project widget
This commit is contained in:
@@ -502,11 +502,6 @@ class NWIndex:
|
|||||||
"""
|
"""
|
||||||
return self._itemIndex.mainItemHeader(tHandle)
|
return self._itemIndex.mainItemHeader(tHandle)
|
||||||
|
|
||||||
def getHandleHeaderIntLevel(self, tHandle):
|
|
||||||
"""Get the integer header level of the first header of a handle.
|
|
||||||
"""
|
|
||||||
return H_LEVEL.get(self._itemIndex.mainItemHeader(tHandle), 0)
|
|
||||||
|
|
||||||
def getTableOfContents(self, maxDepth, skipExcl=True):
|
def getTableOfContents(self, maxDepth, skipExcl=True):
|
||||||
"""Generate a table of contents up to a maximum depth.
|
"""Generate a table of contents up to a maximum depth.
|
||||||
"""
|
"""
|
||||||
|
|||||||
+119
-39
@@ -37,13 +37,13 @@ from PyQt5.QtGui import QIcon
|
|||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMenu, QAction, QFrame,
|
QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMenu, QAction, QFrame,
|
||||||
QDialog, QHeaderView, QWidget, QVBoxLayout, QToolBar, QLabel, QToolButton,
|
QDialog, QHeaderView, QWidget, QVBoxLayout, QToolBar, QLabel, QToolButton,
|
||||||
QSizePolicy
|
QSizePolicy, QInputDialog
|
||||||
)
|
)
|
||||||
|
|
||||||
from novelwriter.core import NWDoc
|
from novelwriter.core import NWDoc
|
||||||
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert
|
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert
|
||||||
from novelwriter.common import minmax
|
|
||||||
from novelwriter.dialogs.itemeditor import GuiItemEditor
|
from novelwriter.dialogs.itemeditor import GuiItemEditor
|
||||||
|
from novelwriter.constants import trConst, nwLabels
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -82,6 +82,8 @@ class GuiProjectWiew(QWidget):
|
|||||||
|
|
||||||
self.setLayout(self.outerBox)
|
self.setLayout(self.outerBox)
|
||||||
|
|
||||||
|
# Connect Signals
|
||||||
|
|
||||||
# Function Mappings
|
# Function Mappings
|
||||||
self.newTreeItem = self.projTree.newTreeItem
|
self.newTreeItem = self.projTree.newTreeItem
|
||||||
self.revealNewTreeItem = self.projTree.revealNewTreeItem
|
self.revealNewTreeItem = self.projTree.revealNewTreeItem
|
||||||
@@ -139,12 +141,19 @@ class GuiProjectWiew(QWidget):
|
|||||||
|
|
||||||
class GuiProjectToolBar(QToolBar):
|
class GuiProjectToolBar(QToolBar):
|
||||||
|
|
||||||
|
ADD_PLAIN = 0
|
||||||
|
ADD_CHAP = 1
|
||||||
|
ADD_SCENE = 2
|
||||||
|
ADD_NOTE = 3
|
||||||
|
ADD_FOLDER = 4
|
||||||
|
|
||||||
def __init__(self, theWidget):
|
def __init__(self, theWidget):
|
||||||
QTreeWidget.__init__(self, theWidget)
|
QTreeWidget.__init__(self, theWidget)
|
||||||
|
|
||||||
logger.debug("Initialising GuiProjectToolBar ...")
|
logger.debug("Initialising GuiProjectToolBar ...")
|
||||||
|
|
||||||
self.mainConf = novelwriter.CONFIG
|
self.mainConf = novelwriter.CONFIG
|
||||||
|
self.theWidget = theWidget
|
||||||
self.theParent = theWidget.theParent
|
self.theParent = theWidget.theParent
|
||||||
self.theProject = theWidget.theParent.theProject
|
self.theProject = theWidget.theParent.theProject
|
||||||
self.theTheme = theWidget.theParent.theTheme
|
self.theTheme = theWidget.theParent.theTheme
|
||||||
@@ -157,14 +166,49 @@ class GuiProjectToolBar(QToolBar):
|
|||||||
self.setContentsMargins(0, 0, 0, 0)
|
self.setContentsMargins(0, 0, 0, 0)
|
||||||
self.setStyleSheet("QToolBar {border: 0px;}")
|
self.setStyleSheet("QToolBar {border: 0px;}")
|
||||||
|
|
||||||
# Novel Selector
|
# Tree Label
|
||||||
self.projLabel = QLabel(self.tr("Project"))
|
self.projLabel = QLabel(self.tr("Project"))
|
||||||
self.projLabel.setContentsMargins(0, 0, mPx, 0)
|
self.projLabel.setContentsMargins(0, 0, mPx, 0)
|
||||||
self.projLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
self.projLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
|
||||||
# Itemss Menu
|
# Items Menu
|
||||||
|
self.mItems = QMenu()
|
||||||
|
|
||||||
|
self.aAddEmpty = self.mItems.addAction(self.tr("Plain Document"))
|
||||||
|
self.aAddEmpty.setIcon(self.theTheme.getIcon("proj_document"))
|
||||||
|
self.aAddEmpty.triggered.connect(lambda: self._forwardNewItem(self.ADD_PLAIN))
|
||||||
|
|
||||||
|
self.aAddChap = self.mItems.addAction(self.tr("Chapter Document"))
|
||||||
|
self.aAddChap.setIcon(self.theTheme.getIcon("proj_chapter"))
|
||||||
|
self.aAddChap.triggered.connect(lambda: self._forwardNewItem(self.ADD_CHAP))
|
||||||
|
|
||||||
|
self.aAddScene = self.mItems.addAction(self.tr("Scene Document"))
|
||||||
|
self.aAddScene.setIcon(self.theTheme.getIcon("proj_scene"))
|
||||||
|
self.aAddScene.triggered.connect(lambda: self._forwardNewItem(self.ADD_SCENE))
|
||||||
|
|
||||||
|
self.aAddNote = self.mItems.addAction(self.tr("Project Note"))
|
||||||
|
self.aAddNote.setIcon(self.theTheme.getIcon("proj_note"))
|
||||||
|
self.aAddNote.triggered.connect(lambda: self._forwardNewItem(self.ADD_NOTE))
|
||||||
|
|
||||||
|
self.aAddFolder = self.mItems.addAction(self.tr("Folder"))
|
||||||
|
self.aAddFolder.setIcon(self.theTheme.getIcon("proj_folder"))
|
||||||
|
self.aAddFolder.triggered.connect(lambda: self._forwardNewItem(self.ADD_FOLDER))
|
||||||
|
|
||||||
|
self.mAddRoot = self.mItems.addMenu(self.tr("Root Folder"))
|
||||||
|
self._addRootFolderEntry(nwItemClass.NOVEL)
|
||||||
|
self._addRootFolderEntry(nwItemClass.ARCHIVE)
|
||||||
|
self.mAddRoot.addSeparator()
|
||||||
|
self._addRootFolderEntry(nwItemClass.PLOT)
|
||||||
|
self._addRootFolderEntry(nwItemClass.CHARACTER)
|
||||||
|
self._addRootFolderEntry(nwItemClass.WORLD)
|
||||||
|
self._addRootFolderEntry(nwItemClass.ARCHIVE)
|
||||||
|
self._addRootFolderEntry(nwItemClass.OBJECT)
|
||||||
|
self._addRootFolderEntry(nwItemClass.ENTITY)
|
||||||
|
self._addRootFolderEntry(nwItemClass.CUSTOM)
|
||||||
|
|
||||||
self.tbItems = QToolButton(self)
|
self.tbItems = QToolButton(self)
|
||||||
self.tbItems.setIcon(self.theTheme.getIcon("add"))
|
self.tbItems.setIcon(self.theTheme.getIcon("add"))
|
||||||
|
self.tbItems.setMenu(self.mItems)
|
||||||
self.tbItems.setPopupMode(QToolButton.InstantPopup)
|
self.tbItems.setPopupMode(QToolButton.InstantPopup)
|
||||||
|
|
||||||
# Settings Menu
|
# Settings Menu
|
||||||
@@ -182,6 +226,45 @@ class GuiProjectToolBar(QToolBar):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Private Slots
|
||||||
|
##
|
||||||
|
|
||||||
|
@pyqtSlot(Enum)
|
||||||
|
def _forwardNewRootFolder(self, itemClass):
|
||||||
|
"""Forward the request for a new root folder to the tree.
|
||||||
|
"""
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.ROOT, itemClass)
|
||||||
|
return
|
||||||
|
|
||||||
|
@pyqtSlot(int)
|
||||||
|
def _forwardNewItem(self, type):
|
||||||
|
"""Forward the request for a new item of a given type.
|
||||||
|
"""
|
||||||
|
if type == self.ADD_PLAIN:
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.FILE, hLevel=0, isNote=False)
|
||||||
|
elif type == self.ADD_CHAP:
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.FILE, hLevel=2, isNote=False)
|
||||||
|
elif type == self.ADD_SCENE:
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.FILE, hLevel=3, isNote=False)
|
||||||
|
elif type == self.ADD_NOTE:
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True)
|
||||||
|
elif type == self.ADD_FOLDER:
|
||||||
|
self.theWidget.projTree.newTreeItem(nwItemType.FOLDER)
|
||||||
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Internal Functions
|
||||||
|
##
|
||||||
|
|
||||||
|
def _addRootFolderEntry(self, itemClass):
|
||||||
|
"""Add a menu entry for a root folder of a given class.
|
||||||
|
"""
|
||||||
|
aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass]))
|
||||||
|
aNew.setIcon(self.theTheme.getIcon(nwLabels.CLASS_ICON[itemClass]))
|
||||||
|
aNew.triggered.connect(lambda: self._forwardNewRootFolder(itemClass))
|
||||||
|
self.mAddRoot.addAction(aNew)
|
||||||
|
|
||||||
# END Class GuiProjectToolBar
|
# END Class GuiProjectToolBar
|
||||||
|
|
||||||
|
|
||||||
@@ -291,7 +374,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self._timeChanged = 0
|
self._timeChanged = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
def newTreeItem(self, itemType, itemClass=None):
|
def newTreeItem(self, itemType, itemClass=None, hLevel=1, isNote=False):
|
||||||
"""Add new item to the tree, with a given itemType (and
|
"""Add new item to the tree, with a given itemType (and
|
||||||
itemClass if Root), and attach it to the selected handle. Also
|
itemClass if Root), and attach it to the selected handle. Also
|
||||||
make sure the item is added in a place it can be added, and that
|
make sure the item is added in a place it can be added, and that
|
||||||
@@ -334,52 +417,49 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
), nwAlert.ERROR)
|
), nwAlert.ERROR)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Ask for label
|
||||||
|
if itemType == nwItemType.FILE:
|
||||||
|
if isNote:
|
||||||
|
newLabel = self.tr("New Note")
|
||||||
|
elif hLevel == 2:
|
||||||
|
newLabel = self.tr("New Chapter")
|
||||||
|
elif hLevel == 3:
|
||||||
|
newLabel = self.tr("New Scene")
|
||||||
|
else:
|
||||||
|
newLabel = self.tr("New Document")
|
||||||
|
else:
|
||||||
|
newLabel = self.tr("New Folder")
|
||||||
|
|
||||||
|
newLabel, dlgOk = QInputDialog.getText(self, "", self.tr("Label:"), text=newLabel)
|
||||||
|
if not dlgOk:
|
||||||
|
logger.info("New item creation cancelled by user")
|
||||||
|
return False
|
||||||
|
|
||||||
# Add the file or folder
|
# Add the file or folder
|
||||||
if itemType == nwItemType.FILE:
|
if itemType == nwItemType.FILE:
|
||||||
if pItem.isNovelLike():
|
tHandle = self.theProject.newFile(newLabel, sHandle)
|
||||||
tHandle = self.theProject.newFile(self.tr("New Document"), sHandle)
|
else:
|
||||||
else:
|
tHandle = self.theProject.newFolder(newLabel, sHandle)
|
||||||
tHandle = self.theProject.newFile(self.tr("New Note"), sHandle)
|
|
||||||
elif itemType == nwItemType.FOLDER:
|
|
||||||
tHandle = self.theProject.newFolder(self.tr("New Folder"), sHandle)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error("Failed to add new item")
|
logger.error("Failed to add new item")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# If there is no handle set, return here. This is a bug
|
# If there is no handle set, return here. This is a bug.
|
||||||
if tHandle is None: # pragma: no cover
|
if tHandle is None: # pragma: no cover
|
||||||
|
logger.error("Internal error")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Add the new item to the tree and open the editor dialog
|
|
||||||
self.revealNewTreeItem(tHandle, nHandle)
|
|
||||||
self.editTreeItem(tHandle)
|
|
||||||
|
|
||||||
# Handle new file creation
|
# Handle new file creation
|
||||||
nwItem = self.theProject.tree[tHandle]
|
if itemType == nwItemType.FILE and hLevel > 0:
|
||||||
if nwItem.itemType != nwItemType.FILE:
|
if self.theProject.writeNewFile(tHandle, hLevel, not isNote):
|
||||||
return True
|
# If successful, update word count
|
||||||
|
wC = self.theProject.index.getCounts(tHandle)[1]
|
||||||
|
self.propagateCount(tHandle, wC)
|
||||||
|
self.theWidget.wordCountsChanged.emit()
|
||||||
|
|
||||||
# This is a new file, so let's add some content
|
# Add the new item to the project tree
|
||||||
newDoc = NWDoc(self.theProject, tHandle)
|
self.revealNewTreeItem(tHandle, nHandle)
|
||||||
if not newDoc.readDocument():
|
|
||||||
if nwItem.itemLayout == nwItemLayout.DOCUMENT:
|
|
||||||
iLvl = self.theProject.index.getHandleHeaderIntLevel(sHandle)
|
|
||||||
hLvl = "#"*minmax(iLvl + 1, 2, 4)
|
|
||||||
newText = f"{hLvl} {nwItem.itemName}\n\n"
|
|
||||||
else:
|
|
||||||
newText = f"# {nwItem.itemName}\n\n"
|
|
||||||
|
|
||||||
pIndex = self.theProject.index
|
|
||||||
|
|
||||||
# Save the text and index it
|
|
||||||
newDoc.writeDocument(newText)
|
|
||||||
pIndex.scanText(tHandle, newText)
|
|
||||||
|
|
||||||
# Get Word Counts
|
|
||||||
_, wC, _ = pIndex.getCounts(tHandle)
|
|
||||||
self.propagateCount(tHandle, wC)
|
|
||||||
self.theWidget.wordCountsChanged.emit()
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-06-05 15:03:00">
|
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-06-06 22:02:03">
|
||||||
<project>
|
<project>
|
||||||
<name>Sample Project</name>
|
<name>Sample Project</name>
|
||||||
<title>Sample Project</title>
|
<title>Sample Project</title>
|
||||||
<author>Jane Smith</author>
|
<author>Jane Smith</author>
|
||||||
<author>Jay Doh</author>
|
<author>Jay Doh</author>
|
||||||
<saveCount>1334</saveCount>
|
<saveCount>1342</saveCount>
|
||||||
<autoCount>225</autoCount>
|
<autoCount>227</autoCount>
|
||||||
<editTime>67746</editTime>
|
<editTime>68090</editTime>
|
||||||
</project>
|
</project>
|
||||||
<settings>
|
<settings>
|
||||||
<doBackup>False</doBackup>
|
<doBackup>False</doBackup>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<spellCheck>True</spellCheck>
|
<spellCheck>True</spellCheck>
|
||||||
<spellLang>None</spellLang>
|
<spellLang>None</spellLang>
|
||||||
<autoOutline>True</autoOutline>
|
<autoOutline>True</autoOutline>
|
||||||
<lastEdited>a520879ca0b45</lastEdited>
|
<lastEdited>636b6aa9b697b</lastEdited>
|
||||||
<lastViewed>636b6aa9b697b</lastViewed>
|
<lastViewed>636b6aa9b697b</lastViewed>
|
||||||
<lastWordCount>1363</lastWordCount>
|
<lastWordCount>1363</lastWordCount>
|
||||||
<novelWordCount>954</novelWordCount>
|
<novelWordCount>954</novelWordCount>
|
||||||
|
|||||||
+17
-13
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:08:21">
|
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-06-06 21:17:27">
|
||||||
<project>
|
<project>
|
||||||
<name>New Project</name>
|
<name>New Project</name>
|
||||||
<title>New Novel</title>
|
<title>New Novel</title>
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
<autoOutline>True</autoOutline>
|
<autoOutline>True</autoOutline>
|
||||||
<lastEdited>None</lastEdited>
|
<lastEdited>None</lastEdited>
|
||||||
<lastViewed>None</lastViewed>
|
<lastViewed>None</lastViewed>
|
||||||
<lastWordCount>0</lastWordCount>
|
<lastWordCount>2</lastWordCount>
|
||||||
<novelWordCount>0</novelWordCount>
|
<novelWordCount>1</novelWordCount>
|
||||||
<notesWordCount>0</notesWordCount>
|
<notesWordCount>1</notesWordCount>
|
||||||
<autoReplace/>
|
<autoReplace/>
|
||||||
<titleFormat>
|
<titleFormat>
|
||||||
<title>%title%</title>
|
<title>%title%</title>
|
||||||
@@ -28,19 +28,19 @@
|
|||||||
<section></section>
|
<section></section>
|
||||||
</titleFormat>
|
</titleFormat>
|
||||||
<status>
|
<status>
|
||||||
<entry key="s000008" count="5" red="100" green="100" blue="100">New</entry>
|
<entry key="s000008" count="7" red="100" green="100" blue="100">New</entry>
|
||||||
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
|
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
|
||||||
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
|
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
|
||||||
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
|
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
|
||||||
</status>
|
</status>
|
||||||
<importance>
|
<importance>
|
||||||
<entry key="i00000c" count="3" red="100" green="100" blue="100">New</entry>
|
<entry key="i00000c" count="4" red="100" green="100" blue="100">New</entry>
|
||||||
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
|
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
|
||||||
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
|
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
|
||||||
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
|
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
|
||||||
</importance>
|
</importance>
|
||||||
</settings>
|
</settings>
|
||||||
<content count="10">
|
<content count="11">
|
||||||
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
|
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
|
||||||
<meta expanded="False"/>
|
<meta expanded="False"/>
|
||||||
<name status="s000008" import="i00000c">Novel</name>
|
<name status="s000008" import="i00000c">Novel</name>
|
||||||
@@ -73,13 +73,17 @@
|
|||||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||||
<name status="s000008" import="i00000c" exported="True">New Scene</name>
|
<name status="s000008" import="i00000c" exported="True">New Scene</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="0000000000028" parent="31489056e0916" root="None" order="0" type="FILE" class="NO_CLASS" layout="NO_LAYOUT">
|
<item handle="0000000000028" parent="0000000000015" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
|
||||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
<meta expanded="False"/>
|
||||||
<name status="None" import="None" exported="True">Hello</name>
|
<name status="s000008" import="i00000c">Stuff</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="0000000000029" parent="71ee45a3c0db9" root="None" order="0" type="FILE" class="NO_CLASS" layout="NO_LAYOUT">
|
<item handle="0000000000029" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
<meta expanded="False" charCount="5" wordCount="1" paraCount="0" cursorPos="0"/>
|
||||||
<name status="None" import="None" exported="True">Jane</name>
|
<name status="s000008" import="i00000c" exported="True">Hello</name>
|
||||||
|
</item>
|
||||||
|
<item handle="000000000002a" parent="0000000000012" root="0000000000012" order="0" type="FILE" class="CHARACTER" layout="NOTE">
|
||||||
|
<meta expanded="False" charCount="4" wordCount="1" paraCount="0" cursorPos="0"/>
|
||||||
|
<name status="s000008" import="i00000c" exported="True">Jane</name>
|
||||||
</item>
|
</item>
|
||||||
</content>
|
</content>
|
||||||
</novelWriterXML>
|
</novelWriterXML>
|
||||||
@@ -232,9 +232,6 @@ def testCoreIndex_CheckThese(mockGUI, fncDir, mockRnd):
|
|||||||
|
|
||||||
assert theIndex.getHandleHeaderLevel(cHandle) == "H1"
|
assert theIndex.getHandleHeaderLevel(cHandle) == "H1"
|
||||||
assert theIndex.getHandleHeaderLevel(nHandle) == "H1"
|
assert theIndex.getHandleHeaderLevel(nHandle) == "H1"
|
||||||
assert theIndex.getHandleHeaderIntLevel(cHandle) == 1
|
|
||||||
assert theIndex.getHandleHeaderIntLevel(nHandle) == 1
|
|
||||||
assert theIndex.getHandleHeaderIntLevel("stuff") == 0
|
|
||||||
|
|
||||||
# Zero Items
|
# Zero Items
|
||||||
assert theIndex.checkThese([], cItem) == []
|
assert theIndex.checkThese([], cItem) == []
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import pytest
|
|||||||
from mock import causeOSError
|
from mock import causeOSError
|
||||||
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
|
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog, QInputDialog
|
||||||
|
|
||||||
from novelwriter.enum import nwItemType, nwWidget
|
from novelwriter.enum import nwItemType, nwWidget
|
||||||
from novelwriter.dialogs import GuiDocMerge, GuiItemEditor
|
from novelwriter.dialogs import GuiDocMerge, GuiItemEditor
|
||||||
@@ -39,6 +39,7 @@ def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
|||||||
# Block message box
|
# Block message box
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
||||||
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
# Create a new project
|
# Create a new project
|
||||||
buildTestProject(nwGUI, fncProj)
|
buildTestProject(nwGUI, fncProj)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import pytest
|
|||||||
from mock import causeOSError
|
from mock import causeOSError
|
||||||
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
|
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog, QInputDialog
|
||||||
|
|
||||||
from novelwriter.enum import nwItemType, nwWidget
|
from novelwriter.enum import nwItemType, nwWidget
|
||||||
from novelwriter.dialogs import GuiDocSplit, GuiItemEditor
|
from novelwriter.dialogs import GuiDocSplit, GuiItemEditor
|
||||||
@@ -40,6 +40,7 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
|||||||
# Block message box
|
# Block message box
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
||||||
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
# Create a new project
|
# Create a new project
|
||||||
buildTestProject(nwGUI, fncProj)
|
buildTestProject(nwGUI, fncProj)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import pytest
|
|||||||
|
|
||||||
from tools import getGuiItem, buildTestProject
|
from tools import getGuiItem, buildTestProject
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QAction, QDialog, QMessageBox
|
from PyQt5.QtWidgets import QAction, QDialog, QMessageBox, QInputDialog
|
||||||
|
|
||||||
from novelwriter.enum import nwItemLayout, nwItemType
|
from novelwriter.enum import nwItemLayout, nwItemType
|
||||||
from novelwriter.dialogs import GuiItemEditor
|
from novelwriter.dialogs import GuiItemEditor
|
||||||
@@ -154,6 +154,7 @@ def testDlgItemEditor_Note(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
|||||||
# Block message box
|
# Block message box
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||||
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
# Create Project and Open Document
|
# Create Project and Open Document
|
||||||
buildTestProject(nwGUI, fncProj)
|
buildTestProject(nwGUI, fncProj)
|
||||||
@@ -165,7 +166,7 @@ def testDlgItemEditor_Note(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
|||||||
# Create Note
|
# Create Note
|
||||||
nwGUI.treeView.projTree.clearSelection()
|
nwGUI.treeView.projTree.clearSelection()
|
||||||
nwGUI.treeView.projTree._getTreeItem("000000000000a").setSelected(True)
|
nwGUI.treeView.projTree._getTreeItem("000000000000a").setSelected(True)
|
||||||
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None)
|
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||||
|
|
||||||
# Open Note
|
# Open Note
|
||||||
assert nwGUI.openDocument("0000000000010")
|
assert nwGUI.openDocument("0000000000010")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from shutil import copyfile
|
|||||||
from tools import cmpFiles, buildTestProject, XML_IGNORE, writeFile
|
from tools import cmpFiles, buildTestProject, XML_IGNORE, writeFile
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtWidgets import QMessageBox, QDialog
|
from PyQt5.QtWidgets import QMessageBox, QDialog, QInputDialog
|
||||||
|
|
||||||
from novelwriter.gui import GuiDocEditor, GuiNovelTree, GuiOutline
|
from novelwriter.gui import GuiDocEditor, GuiNovelTree, GuiOutline
|
||||||
from novelwriter.enum import nwItemType, nwWidget
|
from novelwriter.enum import nwItemType, nwWidget
|
||||||
@@ -173,6 +173,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
|||||||
monkeypatch.setattr(GuiItemEditor, "result", lambda *a: QDialog.Accepted)
|
monkeypatch.setattr(GuiItemEditor, "result", lambda *a: QDialog.Accepted)
|
||||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||||
monkeypatch.setattr(GuiDocEditor, "hasFocus", lambda *a: True)
|
monkeypatch.setattr(GuiDocEditor, "hasFocus", lambda *a: True)
|
||||||
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
# Create new, save, close project
|
# Create new, save, close project
|
||||||
buildTestProject(nwGUI, fncProj)
|
buildTestProject(nwGUI, fncProj)
|
||||||
@@ -241,7 +242,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
|||||||
nwGUI.switchFocus(nwWidget.TREE)
|
nwGUI.switchFocus(nwWidget.TREE)
|
||||||
nwGUI.treeView.projTree.clearSelection()
|
nwGUI.treeView.projTree.clearSelection()
|
||||||
nwGUI.treeView.projTree._getTreeItem("000000000000a").setSelected(True)
|
nwGUI.treeView.projTree._getTreeItem("000000000000a").setSelected(True)
|
||||||
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None)
|
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||||
assert nwGUI.openSelectedItem()
|
assert nwGUI.openSelectedItem()
|
||||||
|
|
||||||
# Type something into the document
|
# Type something into the document
|
||||||
@@ -263,7 +264,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
|||||||
nwGUI.switchFocus(nwWidget.TREE)
|
nwGUI.switchFocus(nwWidget.TREE)
|
||||||
nwGUI.treeView.projTree.clearSelection()
|
nwGUI.treeView.projTree.clearSelection()
|
||||||
nwGUI.treeView.projTree._getTreeItem("0000000000009").setSelected(True)
|
nwGUI.treeView.projTree._getTreeItem("0000000000009").setSelected(True)
|
||||||
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None)
|
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||||
assert nwGUI.openSelectedItem()
|
assert nwGUI.openSelectedItem()
|
||||||
|
|
||||||
# Type something into the document
|
# Type something into the document
|
||||||
@@ -285,7 +286,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
|||||||
nwGUI.switchFocus(nwWidget.TREE)
|
nwGUI.switchFocus(nwWidget.TREE)
|
||||||
nwGUI.treeView.projTree.clearSelection()
|
nwGUI.treeView.projTree.clearSelection()
|
||||||
nwGUI.treeView.projTree._getTreeItem("000000000000b").setSelected(True)
|
nwGUI.treeView.projTree._getTreeItem("000000000000b").setSelected(True)
|
||||||
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None)
|
nwGUI.treeView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||||
assert nwGUI.openSelectedItem()
|
assert nwGUI.openSelectedItem()
|
||||||
|
|
||||||
# Add Some Text
|
# Add Some Text
|
||||||
|
|||||||
@@ -24,9 +24,8 @@ import os
|
|||||||
|
|
||||||
from tools import buildTestProject
|
from tools import buildTestProject
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QAction, QMessageBox
|
from PyQt5.QtWidgets import QAction, QMessageBox, QInputDialog
|
||||||
|
|
||||||
from novelwriter.guimain import GuiMain
|
|
||||||
from novelwriter.gui.projtree import GuiProjectTree
|
from novelwriter.gui.projtree import GuiProjectTree
|
||||||
from novelwriter.enum import nwItemType, nwItemClass
|
from novelwriter.enum import nwItemType, nwItemClass
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
|||||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiMain, "editItem", lambda *a: None)
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
nwTree = nwGUI.treeView
|
nwTree = nwGUI.treeView
|
||||||
|
|
||||||
@@ -89,22 +88,31 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
|||||||
assert nwGUI.theProject.tree["0000000000012"].itemRoot == "0000000000008"
|
assert nwGUI.theProject.tree["0000000000012"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL
|
assert nwGUI.theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL
|
||||||
|
|
||||||
# Add a new file next to the other new file
|
# Add a new chapter next to the other new file
|
||||||
nwTree.setSelectedHandle("0000000000012")
|
nwTree.setSelectedHandle("0000000000012")
|
||||||
assert nwTree.newTreeItem(nwItemType.FILE) is True
|
assert nwTree.newTreeItem(nwItemType.FILE, hLevel=2) is True
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemParent == "0000000000011"
|
assert nwGUI.theProject.tree["0000000000013"].itemParent == "0000000000011"
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemRoot == "0000000000008"
|
assert nwGUI.theProject.tree["0000000000013"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL
|
assert nwGUI.theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL
|
||||||
assert nwGUI.openDocument("0000000000013")
|
assert nwGUI.openDocument("0000000000013")
|
||||||
assert nwGUI.docEditor.getText() == "## New Document\n\n"
|
assert nwGUI.docEditor.getText() == "## New Chapter\n\n"
|
||||||
|
|
||||||
|
# Add a new scene next to the other new file
|
||||||
|
nwTree.setSelectedHandle("0000000000012")
|
||||||
|
assert nwTree.newTreeItem(nwItemType.FILE, hLevel=3) is True
|
||||||
|
assert nwGUI.theProject.tree["0000000000014"].itemParent == "0000000000011"
|
||||||
|
assert nwGUI.theProject.tree["0000000000014"].itemRoot == "0000000000008"
|
||||||
|
assert nwGUI.theProject.tree["0000000000014"].itemClass == nwItemClass.NOVEL
|
||||||
|
assert nwGUI.openDocument("0000000000014")
|
||||||
|
assert nwGUI.docEditor.getText() == "### New Scene\n\n"
|
||||||
|
|
||||||
# Add a new file to the characters folder
|
# Add a new file to the characters folder
|
||||||
nwTree.setSelectedHandle("000000000000a")
|
nwTree.setSelectedHandle("000000000000a")
|
||||||
assert nwTree.newTreeItem(nwItemType.FILE) is True
|
assert nwTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemParent == "000000000000a"
|
assert nwGUI.theProject.tree["0000000000015"].itemParent == "000000000000a"
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemRoot == "000000000000a"
|
assert nwGUI.theProject.tree["0000000000015"].itemRoot == "000000000000a"
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemClass == nwItemClass.CHARACTER
|
assert nwGUI.theProject.tree["0000000000015"].itemClass == nwItemClass.CHARACTER
|
||||||
assert nwGUI.openDocument("0000000000014")
|
assert nwGUI.openDocument("0000000000015")
|
||||||
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
||||||
|
|
||||||
# Make sure the sibling folder bug trap works
|
# Make sure the sibling folder bug trap works
|
||||||
@@ -115,6 +123,12 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
|||||||
assert "Internal error" in caplog.text
|
assert "Internal error" in caplog.text
|
||||||
nwGUI.theProject.tree["0000000000013"].setParent("0000000000011")
|
nwGUI.theProject.tree["0000000000013"].setParent("0000000000011")
|
||||||
|
|
||||||
|
# Cancel during creation
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(QInputDialog, "getText", lambda *a, **k: ("", False))
|
||||||
|
nwTree.setSelectedHandle("0000000000013")
|
||||||
|
assert nwTree.newTreeItem(nwItemType.FILE) is False
|
||||||
|
|
||||||
# Get the trash folder
|
# Get the trash folder
|
||||||
nwTree.projTree._addTrashRoot()
|
nwTree.projTree._addTrashRoot()
|
||||||
trashHandle = nwGUI.theProject.trashFolder()
|
trashHandle = nwGUI.theProject.trashFolder()
|
||||||
@@ -148,7 +162,7 @@ def testGuiProjTree_MoveItems(qtbot, monkeypatch, nwGUI, fncDir, mockRnd):
|
|||||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiMain, "editItem", lambda *a: None)
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
nwTree = nwGUI.treeView
|
nwTree = nwGUI.treeView
|
||||||
|
|
||||||
@@ -272,7 +286,7 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
|||||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiMain, "editItem", lambda *a: None)
|
monkeypatch.setattr(QInputDialog, "getText", lambda *a, text: (text, True))
|
||||||
|
|
||||||
nwTree = nwGUI.treeView
|
nwTree = nwGUI.treeView
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user