Skip to content

Commit 26d97bd

Browse files
committed
Update tests and docs
1 parent c52a37c commit 26d97bd

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

docs/source/usage_shortcuts.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ The main shorcuts are as follows:
9292
":kbd:`Shift`:kbd:`F1`", "Open the local user manual (PDF) if it is available."
9393
":kbd:`Shift`:kbd:`F3`", "Find previous occurrence of search word in current document."
9494
":kbd:`Shift`:kbd:`F6`", "Open the :guilabel:`Project Details` dialog."
95+
":kbd:`Shift`:kbd:`Up`", "Go to the previous item at same level in the project tree."
96+
":kbd:`Shift`:kbd:`Down`", "Go to the next item at same level in the project tree."
97+
":kbd:`Shift`:kbd:`Left`", "Go to the parent item in the project tree."
98+
":kbd:`Shift`:kbd:`Right`", "Go to the first child item in the project tree."
9599

96100
.. note::
97101
On macOS, replace :kbd:`Ctrl` with :kbd:`Cmd`.

tests/test_gui/test_gui_projtree.py

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
You should have received a copy of the GNU General Public License
1919
along with this program. If not, see <https://www.gnu.org/licenses/>.
2020
"""
21+
from __future__ import annotations
2122

2223
import pytest
2324

@@ -32,7 +33,7 @@
3233
from novelwriter import CONFIG
3334
from novelwriter.enum import nwItemLayout, nwItemType, nwItemClass
3435
from novelwriter.guimain import GuiMain
35-
from novelwriter.gui.projtree import GuiProjectTree
36+
from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView
3637
from novelwriter.dialogs.docmerge import GuiDocMerge
3738
from novelwriter.dialogs.docsplit import GuiDocSplit
3839
from novelwriter.dialogs.editlabel import GuiEditLabel
@@ -427,35 +428,35 @@ def testGuiProjTree_PermanentlyDeleteItem(qtbot, caplog, monkeypatch, nwGUI, pro
427428

428429
# Invalid item
429430
caplog.clear()
430-
assert projTree.permanentlyDeleteItem(C.hInvalid) is False
431+
assert projTree.permDeleteItem(C.hInvalid) is False
431432
assert "Could not find tree item for deletion" in caplog.text
432433

433434
# Not deleting root item in use
434435
caplog.clear()
435-
assert projTree.permanentlyDeleteItem(C.hNovelRoot) is False
436+
assert projTree.permDeleteItem(C.hNovelRoot) is False
436437
assert "Root folders can only be deleted when they are empty" in caplog.text
437438
assert C.hNovelRoot in theProject.tree
438439

439440
# Deleting unused root item is allowed
440441
caplog.clear()
441-
assert projTree.permanentlyDeleteItem(C.hPlotRoot) is True
442+
assert projTree.permDeleteItem(C.hPlotRoot) is True
442443
assert C.hPlotRoot not in theProject.tree
443444

444445
# User cancels action
445446
with monkeypatch.context() as mp:
446447
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
447-
assert projTree.permanentlyDeleteItem(C.hTitlePage) is False
448+
assert projTree.permDeleteItem(C.hTitlePage) is False
448449
assert C.hTitlePage in theProject.tree
449450

450451
# Deleting file is OK, and if it is open, it should close
451452
assert nwGUI.openDocument(C.hTitlePage) is True
452453
assert nwGUI.docEditor.docHandle() == C.hTitlePage
453-
assert projTree.permanentlyDeleteItem(C.hTitlePage) is True
454+
assert projTree.permDeleteItem(C.hTitlePage) is True
454455
assert C.hTitlePage not in theProject.tree
455456
assert nwGUI.docEditor.docHandle() is None
456457

457458
# Deleting folder + files recursively is ok
458-
assert projTree.permanentlyDeleteItem(C.hChapterDir) is True
459+
assert projTree.permDeleteItem(C.hChapterDir) is True
459460
assert C.hChapterDir not in theProject.tree
460461
assert C.hChapterDoc not in theProject.tree
461462
assert C.hSceneDoc not in theProject.tree
@@ -904,15 +905,15 @@ def testGuiProjTree_Duplicate(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mock
904905

905906

906907
@pytest.mark.gui
907-
def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
908+
def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd):
908909
"""Test various parts of the project tree class not covered by
909910
other tests.
910911
"""
911912
# Create a project
912913
buildTestProject(nwGUI, projPath)
913914

914-
projView = nwGUI.projView
915-
projTree = nwGUI.projView.projTree
915+
projView: GuiProjectView = nwGUI.projView
916+
projTree: GuiProjectTree = nwGUI.projView.projTree
916917

917918
# Method: initSettings
918919
# ====================
@@ -938,12 +939,12 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
938939

939940
# Try to add an orphaned file to the tree
940941
nHandle = nwGUI.theProject.newFile("Test", C.hNovelRoot)
941-
nwGUI.theProject.tree[nHandle].setParent(None)
942+
nwGUI.theProject.tree[nHandle].setParent(None) # type: ignore
942943
assert projTree.revealNewTreeItem(nHandle) is False
943944

944945
# Try to add an item with unknown parent to the tree
945946
nHandle = nwGUI.theProject.newFile("Test", C.hNovelRoot)
946-
nwGUI.theProject.tree[nHandle].setParent(C.hInvalid)
947+
nwGUI.theProject.tree[nHandle].setParent(C.hInvalid) # type: ignore
947948
assert projTree.revealNewTreeItem(nHandle) is False
948949

949950
# Method: undoLastMove
@@ -971,7 +972,7 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
971972
assert nwGUI.docEditor.docHandle() is None
972973

973974
# When the item cannot be found
974-
projTree._getTreeItem(C.hTitlePage).setSelected(True)
975+
projTree._getTreeItem(C.hTitlePage).setSelected(True) # type: ignore
975976
with monkeypatch.context() as mp:
976977
mp.setattr("novelwriter.core.tree.NWTree.__getitem__", lambda *a: None)
977978
projTree._treeDoubleClick(QTreeWidgetItem(), 0)
@@ -980,14 +981,67 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
980981
# Successfully open a file
981982
projTree._treeDoubleClick(projTree._getTreeItem(C.hTitlePage), 0)
982983
assert nwGUI.docEditor.docHandle() == C.hTitlePage
983-
projTree._getTreeItem(C.hTitlePage).setSelected(False)
984+
projTree._getTreeItem(C.hTitlePage).setSelected(False) # type: ignore
984985

985986
# A non-file item should be expanded instead
986-
projTree._getTreeItem(C.hNovelRoot).setExpanded(False)
987-
projTree._getTreeItem(C.hNovelRoot).setSelected(True)
987+
projTree._getTreeItem(C.hNovelRoot).setExpanded(False) # type: ignore
988+
projTree._getTreeItem(C.hNovelRoot).setSelected(True) # type: ignore
988989
projTree._treeDoubleClick(projTree._getTreeItem(C.hNovelRoot), 1)
989990
assert nwGUI.docEditor.docHandle() == C.hTitlePage
990-
assert projTree._getTreeItem(C.hNovelRoot).isExpanded() is True
991+
assert projTree._getTreeItem(C.hNovelRoot).isExpanded() is True # type: ignore
992+
993+
# Navigate the Tree
994+
# =================
995+
996+
# Expand handles
997+
projTree.setExpandedFromHandle(C.hNovelRoot, True)
998+
projTree.setSelectedHandle(C.hSceneDoc)
999+
assert projTree.getSelectedHandle() == C.hSceneDoc
1000+
1001+
# Move between documents in that folder
1002+
projTree.moveToNextItem(-1)
1003+
assert projTree.getSelectedHandle() == C.hChapterDoc
1004+
projTree.moveToNextItem(-1) # Can't move further up
1005+
assert projTree.getSelectedHandle() == C.hChapterDoc
1006+
projTree.moveToNextItem(1)
1007+
assert projTree.getSelectedHandle() == C.hSceneDoc
1008+
projTree.moveToNextItem(1) # Can't move further down
1009+
assert projTree.getSelectedHandle() == C.hSceneDoc
1010+
1011+
# Move up/down the parent/child hierarchy
1012+
projTree.moveToLevel(-1)
1013+
assert projTree.getSelectedHandle() == C.hChapterDir
1014+
projTree.moveToLevel(-1)
1015+
assert projTree.getSelectedHandle() == C.hNovelRoot
1016+
projTree.moveToLevel(-1) # Can't move further up
1017+
assert projTree.getSelectedHandle() == C.hNovelRoot
1018+
projTree.moveToLevel(1)
1019+
assert projTree.getSelectedHandle() == C.hTitlePage
1020+
projTree.moveToLevel(1) # Can't move further down
1021+
assert projTree.getSelectedHandle() == C.hTitlePage
1022+
1023+
# Move between roots
1024+
projTree.setSelectedHandle(C.hNovelRoot)
1025+
projTree.moveToNextItem(1)
1026+
assert projTree.getSelectedHandle() == C.hPlotRoot
1027+
projTree.moveToNextItem(1)
1028+
assert projTree.getSelectedHandle() == C.hCharRoot
1029+
projTree.moveToNextItem(1)
1030+
assert projTree.getSelectedHandle() == C.hWorldRoot
1031+
projTree.moveToNextItem(1) # Can't move further down
1032+
assert projTree.getSelectedHandle() == C.hWorldRoot
1033+
1034+
# When nothing is selected, nothing happens
1035+
projTree.clearSelection()
1036+
assert projTree.getSelectedHandle() is None
1037+
projTree.moveToNextItem(-1)
1038+
assert projTree.getSelectedHandle() is None
1039+
projTree.moveToNextItem(1)
1040+
assert projTree.getSelectedHandle() is None
1041+
projTree.moveToLevel(-1)
1042+
assert projTree.getSelectedHandle() is None
1043+
projTree.moveToLevel(1)
1044+
assert projTree.getSelectedHandle() is None
9911045

9921046
# qtbot.stop()
9931047

0 commit comments

Comments
 (0)