Clean up Main GUI inheritance

This commit is contained in:
Veronica Berglyd Olsen
2024-05-02 22:13:35 +02:00
parent e75b5e012c
commit 2b8338f537
10 changed files with 68 additions and 96 deletions
+3 -7
View File
@@ -25,14 +25,13 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from pathlib import Path
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtWidgets import (
QAbstractItemView, QApplication, QDialog, QDialogButtonBox, QFileDialog,
QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout
QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
@@ -42,9 +41,6 @@ from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.types import QtDialogClose, QtDialogSave
if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
logger = logging.getLogger(__name__)
@@ -52,8 +48,8 @@ class GuiWordList(QDialog):
newWordListReady = pyqtSignal()
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
logger.debug("Create: GuiWordList")
self.setObjectName("GuiWordList")
+7 -14
View File
@@ -36,7 +36,6 @@ import logging
from enum import Enum
from time import time
from typing import TYPE_CHECKING
from PyQt5.QtCore import (
QObject, QPoint, QRegularExpression, QRunnable, Qt, QTimer, pyqtSignal,
@@ -69,9 +68,6 @@ from novelwriter.types import (
QtMoveAnchor, QtMoveLeft, QtMoveRight
)
if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
logger = logging.getLogger(__name__)
@@ -107,15 +103,14 @@ class GuiDocEditor(QPlainTextEdit):
requestProjectItemSelected = pyqtSignal(str, bool)
requestProjectItemRenamed = pyqtSignal(str, str)
requestNewNoteCreation = pyqtSignal(str, nwItemClass)
requestNextDocument = pyqtSignal(str, bool)
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
logger.debug("Create: GuiDocEditor")
# Class Variables
self.mainGui = mainGui
self._nwDocument = None
self._nwItem = None
@@ -1319,9 +1314,8 @@ class GuiDocEditor(QPlainTextEdit):
self.docSearch.setResultCount(0, 0)
self._lastFind = None
if CONFIG.searchNextFile and not goBack:
self.mainGui.openNextDocument(
self._docHandle, wrapAround=CONFIG.searchLoop
)
self.requestNextDocument.emit(self._docHandle, CONFIG.searchLoop)
QApplication.processEvents()
self.beginSearch()
self.setFocus()
return
@@ -1340,9 +1334,8 @@ class GuiDocEditor(QPlainTextEdit):
if resIdx > maxIdx and self._docHandle:
if CONFIG.searchNextFile and not goBack:
self.mainGui.openNextDocument(
self._docHandle, wrapAround=CONFIG.searchLoop
)
self.requestNextDocument.emit(self._docHandle, CONFIG.searchLoop)
QApplication.processEvents()
self.beginSearch()
self.setFocus()
return
+4 -12
View File
@@ -29,9 +29,8 @@ import logging
from enum import Enum
from time import time
from typing import TYPE_CHECKING
from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSlot, pyqtSignal
from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
from PyQt5.QtWidgets import (
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
@@ -52,9 +51,6 @@ from novelwriter.types import (
QtUserRole
)
if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
logger = logging.getLogger(__name__)
@@ -74,10 +70,8 @@ class GuiNovelView(QWidget):
selectedItemChanged = pyqtSignal(str)
openDocumentRequest = pyqtSignal(str, Enum, str, bool)
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
self.mainGui = mainGui
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
# Build GUI
self.novelTree = GuiNovelTree(self)
@@ -202,7 +196,6 @@ class GuiNovelToolBar(QWidget):
logger.debug("Create: GuiNovelToolBar")
self.novelView = novelView
self.mainGui = novelView.mainGui
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
@@ -378,7 +371,6 @@ class GuiNovelTree(QTreeWidget):
logger.debug("Create: GuiNovelTree")
self.novelView = novelView
self.mainGui = novelView.mainGui
# Internal Variables
self._treeMap = {}
@@ -493,7 +485,7 @@ class GuiNovelTree(QTreeWidget):
if rootHandle is None:
rootHandle = SHARED.project.tree.findRoot(nwItemClass.NOVEL)
treeChanged = self.mainGui.projView.changedSince(self._lastBuild)
treeChanged = SHARED.mainGui.projView.changedSince(self._lastBuild)
indexChanged = SHARED.project.index.rootChangedSince(rootHandle, self._lastBuild)
if not (treeChanged or indexChanged or overRide):
logger.debug("No changes have been made to the novel index")
+7 -15
View File
@@ -30,7 +30,6 @@ import logging
from enum import Enum
from time import time
from typing import TYPE_CHECKING
from PyQt5.QtCore import QPoint, Qt, QTimer, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
@@ -57,9 +56,6 @@ from novelwriter.types import (
QtUserRole
)
if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
logger = logging.getLogger(__name__)
@@ -81,10 +77,8 @@ class GuiProjectView(QWidget):
# Requests for the main GUI
projectSettingsRequest = pyqtSignal(int)
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
self.mainGui = mainGui
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
# Build GUI
self.projTree = GuiProjectTree(self)
@@ -263,7 +257,6 @@ class GuiProjectToolBar(QWidget):
self.projView = projView
self.projTree = projView.projTree
self.mainGui = projView.mainGui
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
@@ -499,7 +492,6 @@ class GuiProjectTree(QTreeWidget):
logger.debug("Create: GuiProjectTree")
self.projView = projView
self.mainGui = projView.mainGui
# Internal Variables
self._treeMap: dict[str, QTreeWidgetItem] = {}
@@ -1010,8 +1002,7 @@ class GuiProjectTree(QTreeWidget):
trItemP.takeChild(tIndex)
for dHandle in reversed(self.getTreeFromHandle(tHandle)):
if self.mainGui.docEditor.docHandle == dHandle:
self.mainGui.closeDocument()
SHARED.closeDocument(dHandle)
SHARED.project.removeItem(dHandle)
self._treeMap.pop(dHandle, None)
@@ -1410,7 +1401,7 @@ class GuiProjectTree(QTreeWidget):
if not newFile:
itemList.remove(tHandle)
dlgMerge = GuiDocMerge(self.mainGui, tHandle, itemList)
dlgMerge = GuiDocMerge(SHARED.mainGui, tHandle, itemList)
dlgMerge.exec()
if dlgMerge.result() == QDialog.DialogCode.Accepted:
@@ -1451,7 +1442,8 @@ class GuiProjectTree(QTreeWidget):
if newFile:
self.revealNewTreeItem(mHandle, nHandle=tHandle, wordCount=True)
self.mainGui.openDocument(mHandle, doScroll=True)
self.projView.openDocumentRequest.emit(mHandle, nwDocMode.EDIT, "", False)
self.projView.setSelectedHandle(mHandle, doScroll=True)
if mrgData.get("moveToTrash", False):
for sHandle in reversed(mrgData.get("finalItems", [])):
@@ -1480,7 +1472,7 @@ class GuiProjectTree(QTreeWidget):
logger.error("Only valid document items can be split")
return False
dlgSplit = GuiDocSplit(self.mainGui, tHandle)
dlgSplit = GuiDocSplit(SHARED.mainGui, tHandle)
dlgSplit.exec()
if dlgSplit.result() == QDialog.DialogCode.Accepted:
+2 -2
View File
@@ -27,8 +27,8 @@ import logging
from typing import TYPE_CHECKING
from PyQt5.QtGui import QPalette
from PyQt5.QtCore import QEvent, QPoint, QSize, pyqtSignal
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QMenu, QVBoxLayout, QWidget
from novelwriter import CONFIG, SHARED
@@ -58,7 +58,7 @@ class GuiSideBar(QWidget):
iSz = QSize(iPx, iPx)
self.setContentsMargins(0, 0, 0, 0)
self.installEventFilter(StatusTipFilter(mainGui))
self.installEventFilter(StatusTipFilter(self.mainGui))
# Buttons
self.tbProject = NIconToolButton(self, iSz)
+6 -8
View File
@@ -27,26 +27,23 @@ import logging
from datetime import datetime
from time import time
from typing import TYPE_CHECKING, Literal
from typing import Literal
from PyQt5.QtCore import pyqtSlot, QLocale
from PyQt5.QtWidgets import QApplication, QStatusBar, QLabel
from PyQt5.QtCore import QLocale, pyqtSlot
from PyQt5.QtWidgets import QApplication, QLabel, QStatusBar, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter.common import formatTime
from novelwriter.constants import nwConst
from novelwriter.extensions.statusled import StatusLED
if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
logger = logging.getLogger(__name__)
class GuiMainStatus(QStatusBar):
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
logger.debug("Create: GuiMainStatus")
@@ -238,6 +235,7 @@ class GuiMainStatus(QStatusBar):
before starting novelWriter.
"""
import tracemalloc
from collections import Counter
widgets = QApplication.allWidgets()
+22 -27
View File
@@ -263,6 +263,7 @@ class GuiMain(QMainWindow):
self.docEditor.requestProjectItemRenamed.connect(self.projView.renameTreeItem)
self.docEditor.requestNewNoteCreation.connect(self.projView.createNewNote)
self.docEditor.docTextChanged.connect(self.projSearch.textChanged)
self.docEditor.requestNextDocument.connect(self.openNextDocument)
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
@@ -549,36 +550,30 @@ class GuiMain(QMainWindow):
return True
def openNextDocument(self, tHandle: str, wrapAround: bool = False) -> bool:
@pyqtSlot(str, bool)
def openNextDocument(self, tHandle: str, wrapAround: bool) -> None:
"""Open the next document in the project tree, following the
document with the given handle. Stop when reaching the end.
"""
if not SHARED.hasProject:
logger.error("No project open")
return False
nHandle = None # The next handle after tHandle
fHandle = None # The first file handle we encounter
foundIt = False # We've found tHandle, pick the next we see
for tItem in SHARED.project.tree:
if not tItem.isFileType():
continue
if fHandle is None:
fHandle = tItem.itemHandle
if tItem.itemHandle == tHandle:
foundIt = True
elif foundIt:
nHandle = tItem.itemHandle
break
if nHandle is not None:
self.openDocument(nHandle, tLine=1, doScroll=True)
return True
elif wrapAround:
self.openDocument(fHandle, tLine=1, doScroll=True)
return False
return False
if SHARED.hasProject:
nHandle = None # The next handle after tHandle
fHandle = None # The first file handle we encounter
foundIt = False # We've found tHandle, pick the next we see
for tItem in SHARED.project.tree:
if not tItem.isFileType():
continue
if fHandle is None:
fHandle = tItem.itemHandle
if tItem.itemHandle == tHandle:
foundIt = True
elif foundIt:
nHandle = tItem.itemHandle
break
if nHandle is not None:
self.openDocument(nHandle, tLine=1, doScroll=True)
elif wrapAround:
self.openDocument(fHandle, tLine=1, doScroll=True)
return
@pyqtSlot()
def saveDocument(self) -> None:
+6
View File
@@ -171,6 +171,12 @@ class SharedData(QObject):
logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
return
def closeDocument(self, tHandle: str | None = None) -> None:
"""Close the document editor, optionally a specific document."""
if tHandle is None or tHandle == self.mainGui.docEditor.docHandle:
self.mainGui.closeDocument()
return
def saveDocument(self) -> None:
"""Forward save document call to main GUI."""
self.mainGui.saveDocument()
+2 -2
View File
@@ -69,8 +69,8 @@ class GuiWritingStats(NToolDialog):
FMT_JSON = 0
FMT_CSV = 1
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
def __init__(self, parent: GuiMain) -> None:
super().__init__(parent=parent)
logger.debug("Create: GuiWritingStats")
self.setObjectName("GuiWritingStats")
+9 -9
View File
@@ -21,24 +21,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations
import sys
import pytest
from shutil import copyfile
from tools import C, NWD_IGNORE, cmpFiles, buildTestProject, XML_IGNORE
import pytest
from PyQt5.QtGui import QPalette
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMenu, QInputDialog
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QInputDialog, QMenu
from novelwriter import CONFIG, SHARED
from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.enum import nwItemType, nwView, nwWidget
from novelwriter.gui.outline import GuiOutlineView
from novelwriter.gui.projtree import GuiProjectTree
from novelwriter.gui.doceditor import GuiDocEditor
from novelwriter.gui.noveltree import GuiNovelView
from novelwriter.gui.outline import GuiOutlineView
from novelwriter.gui.projtree import GuiProjectTree
from novelwriter.tools.welcome import GuiWelcome
from novelwriter.dialogs.editlabel import GuiEditLabel
from tests.tools import NWD_IGNORE, XML_IGNORE, C, buildTestProject, cmpFiles
KEY_DELAY = 1
@@ -50,7 +51,6 @@ def testGuiMain_ProjectBlocker(nwGUI):
assert nwGUI.closeProject() is True
assert nwGUI.saveProject() is False
assert nwGUI.openDocument(None) is False
assert nwGUI.openNextDocument(None) is False
assert nwGUI.viewDocument(None) is False
assert nwGUI.importDocument() is False
@@ -84,7 +84,7 @@ def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, projPath):
nwGUI.closeProject()
# Check that latest release info updated
CONFIG.lastNotes != "0x0"
assert CONFIG.lastNotes != "0x0"
# Check that project open dialog launches
nwGUI.postLaunchTasks(None)