Improve dialog handling (#1844)
This commit is contained in:
@@ -27,20 +27,20 @@ import logging
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QColor
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QTextBrowser, QVBoxLayout,
|
||||
QWidget
|
||||
QDialogButtonBox, QHBoxLayout, QLabel, QTextBrowser, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import cssCol, readTextFile
|
||||
from novelwriter.extensions.configlayout import NColourLabel
|
||||
from novelwriter.extensions.modified import NNonBlockingDialog
|
||||
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
||||
from novelwriter.types import QtAlignRightTop, QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiAbout(QDialog):
|
||||
class GuiAbout(NNonBlockingDialog):
|
||||
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
@@ -6,6 +6,8 @@ File History:
|
||||
Created: 2024-02-01 [2.3b1] NComboBox
|
||||
Created: 2024-02-01 [2.3b1] NSpinBox
|
||||
Created: 2024-02-01 [2.3b1] NDoubleSpinBox
|
||||
Created: 2024-05-01 [2.5b1] NToolDialog
|
||||
Created: 2024-05-01 [2.5b1] NNonBlockingDialog
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2024, Veronica Berglyd Olsen
|
||||
@@ -29,9 +31,52 @@ from enum import Enum
|
||||
|
||||
from PyQt5.QtCore import QSize, Qt
|
||||
from PyQt5.QtGui import QWheelEvent
|
||||
from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QComboBox, QDialog, QDoubleSpinBox, QSpinBox, QToolButton,
|
||||
QWidget
|
||||
)
|
||||
|
||||
from novelwriter import SHARED
|
||||
from novelwriter import CONFIG, SHARED
|
||||
|
||||
|
||||
class NToolDialog(QDialog):
|
||||
|
||||
def __init__(self, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent=parent)
|
||||
self.setModal(False)
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
return
|
||||
|
||||
def activateDialog(self) -> None:
|
||||
"""Helper function to activate dialog on various systems."""
|
||||
self.show()
|
||||
if CONFIG.osWindows:
|
||||
self.activateWindow()
|
||||
self.raise_()
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
# END Class NToolDialog
|
||||
|
||||
|
||||
class NNonBlockingDialog(QDialog):
|
||||
|
||||
def __init__(self, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent=parent)
|
||||
self.setModal(True)
|
||||
return
|
||||
|
||||
def activateDialog(self) -> None:
|
||||
"""Helper function to activate dialog on various systems."""
|
||||
self.show()
|
||||
if CONFIG.osWindows:
|
||||
self.activateWindow()
|
||||
self.raise_()
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
# END Class NNonBlockingDialog
|
||||
|
||||
|
||||
class NComboBox(QComboBox):
|
||||
|
||||
+11
-26
@@ -23,18 +23,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from time import time
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor, QIcon
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, QSplitter,
|
||||
QStackedWidget, QVBoxLayout, QWidget
|
||||
QApplication, QFileDialog, QHBoxLayout, QMainWindow, QMessageBox,
|
||||
QShortcut, QSplitter, QStackedWidget, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED, __hexversion__, __version__
|
||||
@@ -44,7 +44,7 @@ from novelwriter.dialogs.about import GuiAbout
|
||||
from novelwriter.dialogs.preferences import GuiPreferences
|
||||
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
||||
from novelwriter.dialogs.wordlist import GuiWordList
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwWidget, nwView
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwView, nwWidget
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.gui.docviewer import GuiDocViewer
|
||||
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
|
||||
@@ -794,10 +794,7 @@ class GuiMain(QMainWindow):
|
||||
"""Open the novel details dialog."""
|
||||
if SHARED.hasProject:
|
||||
dialog = GuiNovelDetails(self)
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
QApplication.processEvents()
|
||||
dialog.activateDialog()
|
||||
dialog.updateValues()
|
||||
return
|
||||
|
||||
@@ -807,10 +804,7 @@ class GuiMain(QMainWindow):
|
||||
if SHARED.hasProject:
|
||||
if (dialog := SHARED.findTopLevelWidget(GuiManuscript)) is None:
|
||||
dialog = GuiManuscript(self)
|
||||
dialog.setModal(False)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
QApplication.processEvents()
|
||||
dialog.activateDialog()
|
||||
dialog.loadContent()
|
||||
return
|
||||
|
||||
@@ -829,10 +823,7 @@ class GuiMain(QMainWindow):
|
||||
if SHARED.hasProject:
|
||||
if (dialog := SHARED.findTopLevelWidget(GuiWritingStats)) is None:
|
||||
dialog = GuiWritingStats(self)
|
||||
dialog.setModal(False)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
QApplication.processEvents()
|
||||
dialog.activateDialog()
|
||||
dialog.populateGUI()
|
||||
return
|
||||
|
||||
@@ -840,10 +831,7 @@ class GuiMain(QMainWindow):
|
||||
def showAboutNWDialog(self) -> None:
|
||||
"""Show the novelWriter about dialog."""
|
||||
dialog = GuiAbout(self)
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
QApplication.processEvents()
|
||||
dialog.activateDialog()
|
||||
dialog.populateGUI()
|
||||
return
|
||||
|
||||
@@ -858,10 +846,7 @@ class GuiMain(QMainWindow):
|
||||
def showDictionariesDialog(self) -> None:
|
||||
"""Show the download dictionaries dialog."""
|
||||
dialog = GuiDictionaries(self)
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
QApplication.processEvents()
|
||||
dialog.activateDialog()
|
||||
if not dialog.initDialog():
|
||||
dialog.close()
|
||||
SHARED.error(self.tr("Could not initialise the dialog."))
|
||||
|
||||
@@ -31,20 +31,20 @@ from zipfile import ZipFile
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QTextCursor
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QDialog, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout,
|
||||
QLabel, QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget
|
||||
QApplication, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout, QLabel,
|
||||
QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import formatFileFilter, openExternalPath, formatInt, getFileSize
|
||||
from novelwriter.common import formatFileFilter, formatInt, getFileSize, openExternalPath
|
||||
from novelwriter.error import formatException
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.extensions.modified import NIconToolButton, NNonBlockingDialog
|
||||
from novelwriter.types import QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiDictionaries(QDialog):
|
||||
class GuiDictionaries(NNonBlockingDialog):
|
||||
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
@@ -28,16 +28,15 @@ import logging
|
||||
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import QTimer, QUrl, Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
|
||||
from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter
|
||||
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
|
||||
QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton,
|
||||
QSplitter, QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget,
|
||||
QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
|
||||
QLabel, QListWidget, QListWidgetItem, QPushButton, QSplitter,
|
||||
QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -48,7 +47,7 @@ from novelwriter.core.tohtml import ToHtml
|
||||
from novelwriter.core.tokenizer import HeadingFormatter
|
||||
from novelwriter.error import logException
|
||||
from novelwriter.extensions.circularprogress import NProgressCircle
|
||||
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
|
||||
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
|
||||
from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.tools.manusbuild import GuiManuscriptBuild
|
||||
from novelwriter.tools.manussettings import GuiBuildSettings
|
||||
@@ -57,13 +56,10 @@ from novelwriter.types import (
|
||||
QtSizeExpanding, QtSizeIgnored, QtUserRole
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiManuscript(QDialog):
|
||||
class GuiManuscript(NToolDialog):
|
||||
"""GUI Tools: Manuscript Tool
|
||||
|
||||
The dialog displays all the users build definitions, a preview panel
|
||||
@@ -73,15 +69,11 @@ class GuiManuscript(QDialog):
|
||||
|
||||
D_KEY = QtUserRole
|
||||
|
||||
def __init__(self, mainGui: GuiMain) -> None:
|
||||
super().__init__(parent=mainGui)
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
logger.debug("Create: GuiManuscript")
|
||||
self.setObjectName("GuiManuscript")
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
|
||||
self.mainGui = mainGui
|
||||
|
||||
self._builds = BuildCollection(SHARED.project)
|
||||
self._buildMap: dict[str, QListWidgetItem] = {}
|
||||
@@ -280,7 +272,7 @@ class GuiManuscript(QDialog):
|
||||
dialog open.
|
||||
"""
|
||||
self._saveSettings()
|
||||
for obj in self.mainGui.children():
|
||||
for obj in SHARED.mainGui.children():
|
||||
# Make sure we don't have any settings windows open
|
||||
if isinstance(obj, GuiBuildSettings) and obj.isVisible():
|
||||
obj.close()
|
||||
@@ -319,6 +311,8 @@ class GuiManuscript(QDialog):
|
||||
"""Delete the currently selected build settings entry."""
|
||||
if build := self._getSelectedBuild():
|
||||
if SHARED.question(self.tr("Delete build '{0}'?".format(build.name))):
|
||||
if dialog := self._findSettingsDialog(build.buildID):
|
||||
dialog.close()
|
||||
self._builds.removeBuild(build.buildID)
|
||||
self._updateBuildsList()
|
||||
return
|
||||
@@ -467,22 +461,14 @@ class GuiManuscript(QDialog):
|
||||
|
||||
def _openSettingsDialog(self, build: BuildSettings) -> None:
|
||||
"""Open the build settings dialog."""
|
||||
for obj in self.mainGui.children():
|
||||
# Don't open a second dialog if one exists
|
||||
if isinstance(obj, GuiBuildSettings):
|
||||
if obj.buildID == build.buildID:
|
||||
logger.debug("Found instance of GuiBuildSettings")
|
||||
obj.show()
|
||||
obj.raise_()
|
||||
return
|
||||
if dialog := self._findSettingsDialog(build.buildID):
|
||||
dialog.activateDialog()
|
||||
return
|
||||
|
||||
dlgSettings = GuiBuildSettings(self.mainGui, build)
|
||||
dlgSettings.setModal(False)
|
||||
dlgSettings.show()
|
||||
dlgSettings.raise_()
|
||||
QApplication.processEvents()
|
||||
dlgSettings.loadContent()
|
||||
dlgSettings.newSettingsReady.connect(self._processNewSettings)
|
||||
dialog = GuiBuildSettings(SHARED.mainGui, build)
|
||||
dialog.activateDialog()
|
||||
dialog.loadContent()
|
||||
dialog.newSettingsReady.connect(self._processNewSettings)
|
||||
|
||||
return
|
||||
|
||||
@@ -507,6 +493,15 @@ class GuiManuscript(QDialog):
|
||||
self._updateBuildsList()
|
||||
return
|
||||
|
||||
def _findSettingsDialog(self, buildID: str) -> GuiBuildSettings | None:
|
||||
"""Return an open build settings dialog for a given build, if
|
||||
one exists.
|
||||
"""
|
||||
for obj in SHARED.mainGui.children():
|
||||
if isinstance(obj, GuiBuildSettings) and obj.buildID == buildID:
|
||||
return obj
|
||||
return None
|
||||
|
||||
# END Class GuiManuscript
|
||||
|
||||
|
||||
|
||||
@@ -25,13 +25,11 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import QEvent, Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtCore import QEvent, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFontDialog,
|
||||
QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu,
|
||||
QAbstractButton, QAbstractItemView, QDialogButtonBox, QFontDialog, QFrame,
|
||||
QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu,
|
||||
QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, QTreeWidget,
|
||||
QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
)
|
||||
@@ -42,7 +40,9 @@ from novelwriter.core.buildsettings import BuildSettings, FilterMode
|
||||
from novelwriter.extensions.configlayout import (
|
||||
NColourLabel, NFixedPage, NScrollableForm, NScrollablePage
|
||||
)
|
||||
from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox
|
||||
from novelwriter.extensions.modified import (
|
||||
NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox, NToolDialog
|
||||
)
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.extensions.switchbox import NSwitchBox
|
||||
@@ -51,13 +51,10 @@ from novelwriter.types import (
|
||||
QtRoleApply, QtRoleReject, QtUserRole
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiBuildSettings(QDialog):
|
||||
class GuiBuildSettings(NToolDialog):
|
||||
"""GUI Tools: Manuscript Build Settings Dialog
|
||||
|
||||
The main tool for configuring manuscript builds. It's a GUI tool for
|
||||
@@ -72,13 +69,11 @@ class GuiBuildSettings(QDialog):
|
||||
|
||||
newSettingsReady = pyqtSignal(BuildSettings)
|
||||
|
||||
def __init__(self, mainGui: GuiMain, build: BuildSettings) -> None:
|
||||
super().__init__(parent=mainGui)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
logger.debug("Create: GuiBuildSettings")
|
||||
self.setObjectName("GuiBuildSettings")
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
|
||||
self._build = build
|
||||
|
||||
@@ -296,8 +291,8 @@ class _FilterTab(NFixedPage):
|
||||
F_INCLUDED = 2
|
||||
F_EXCLUDED = 3
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
||||
self._build = build
|
||||
@@ -586,8 +581,8 @@ class _HeadingsTab(NScrollablePage):
|
||||
EDIT_HSCENE = 5
|
||||
EDIT_SECTION = 6
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self._build = build
|
||||
self._editing = 0
|
||||
@@ -972,8 +967,8 @@ class _HeadingSyntaxHighlighter(QSyntaxHighlighter):
|
||||
|
||||
class _ContentTab(NScrollableForm):
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self._build = build
|
||||
|
||||
@@ -1057,8 +1052,8 @@ class _ContentTab(NScrollableForm):
|
||||
|
||||
class _FormatTab(NScrollableForm):
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self._build = build
|
||||
self._unitScale = 1.0
|
||||
@@ -1324,8 +1319,8 @@ class _FormatTab(NScrollableForm):
|
||||
|
||||
class _OutputTab(NScrollableForm):
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self._build = build
|
||||
|
||||
|
||||
@@ -23,21 +23,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
import logging
|
||||
import math
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QDialog, QDialogButtonBox, QFormLayout, QGridLayout,
|
||||
QHBoxLayout, QLabel, QSpinBox, QStackedWidget, QTreeWidget,
|
||||
QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
QAbstractItemView, QDialogButtonBox, QFormLayout, QGridLayout, QHBoxLayout,
|
||||
QLabel, QSpinBox, QStackedWidget, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import formatTime, numberToRoman
|
||||
from novelwriter.constants import nwUnicode
|
||||
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
|
||||
from novelwriter.extensions.modified import NNonBlockingDialog
|
||||
from novelwriter.extensions.novelselector import NovelSelector
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
@@ -46,7 +47,7 @@ from novelwriter.types import QtAlignRight, QtDecoration, QtDialogClose
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiNovelDetails(QDialog):
|
||||
class GuiNovelDetails(NNonBlockingDialog):
|
||||
|
||||
PAGE_OVERVIEW = 1
|
||||
PAGE_CONTENTS = 2
|
||||
|
||||
@@ -32,15 +32,16 @@ from typing import TYPE_CHECKING
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor, QPixmap
|
||||
from PyQt5.QtWidgets import (
|
||||
QAction, QApplication, QDialog, QDialogButtonBox, QFileDialog, QGridLayout,
|
||||
QAction, QApplication, QDialogButtonBox, QFileDialog, QGridLayout,
|
||||
QGroupBox, QHBoxLayout, QLabel, QMenu, QSpinBox, QTreeWidget,
|
||||
QTreeWidgetItem
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax
|
||||
from novelwriter.common import checkInt, checkIntTuple, formatTime, minmax
|
||||
from novelwriter.constants import nwConst
|
||||
from novelwriter.error import formatException
|
||||
from novelwriter.extensions.modified import NToolDialog
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import (
|
||||
QtAlignLeftMiddle, QtAlignRight, QtAlignRightMiddle, QtDecoration,
|
||||
@@ -53,7 +54,7 @@ if TYPE_CHECKING: # pragma: no cover
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiWritingStats(QDialog):
|
||||
class GuiWritingStats(NToolDialog):
|
||||
"""GUI Tools: Writing Statistics
|
||||
|
||||
Displays data from the NWSessionLog object.
|
||||
@@ -73,8 +74,6 @@ class GuiWritingStats(QDialog):
|
||||
|
||||
logger.debug("Create: GuiWritingStats")
|
||||
self.setObjectName("GuiWritingStats")
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
|
||||
self.logData = []
|
||||
self.filterData = []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="2.5a2" hexVersion="0x020500a1" fileVersion="1.5" fileRevision="4" timeStamp="2024-04-18 17:57:37">
|
||||
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1916" autoCount="274" editTime="87487">
|
||||
<novelWriterXML appVersion="2.5a3" hexVersion="0x020500a3" fileVersion="1.5" fileRevision="4" timeStamp="2024-05-01 19:43:08">
|
||||
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1917" autoCount="274" editTime="87503">
|
||||
<name>Sample Project</name>
|
||||
<author>Jane Smith</author>
|
||||
</project>
|
||||
|
||||
@@ -20,18 +20,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
from pytestqt.qtbot import QtBot
|
||||
|
||||
import pytest
|
||||
|
||||
from mocked import causeOSError
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtPrintSupport import QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import QAction, QListWidgetItem
|
||||
from pytestqt.qtbot import QtBot
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwHeadFmt
|
||||
@@ -98,7 +98,14 @@ def testManuscript_Builds(qtbot: QtBot, nwGUI: GuiMain, projPath: Path):
|
||||
manus.show()
|
||||
manus.loadContent()
|
||||
|
||||
# Delete the default build
|
||||
# Delete the default build, while it is open
|
||||
manus.buildList.clearSelection()
|
||||
manus.buildList.setCurrentRow(0)
|
||||
with qtbot.waitSignal(manus.tbEdit.clicked, timeout=5000):
|
||||
manus.tbEdit.click()
|
||||
|
||||
manus._editSelectedBuild()
|
||||
|
||||
manus.buildList.clearSelection()
|
||||
manus.buildList.setCurrentRow(0)
|
||||
manus.tbDel.click()
|
||||
@@ -127,8 +134,10 @@ def testManuscript_Builds(qtbot: QtBot, nwGUI: GuiMain, projPath: Path):
|
||||
# Edit the new build
|
||||
manus.buildList.clearSelection()
|
||||
manus.buildList.setCurrentRow(0)
|
||||
manus.tbEdit.click()
|
||||
with qtbot.waitSignal(manus.tbEdit.clicked, timeout=5000):
|
||||
manus.tbEdit.click()
|
||||
|
||||
manus._editSelectedBuild()
|
||||
bSettings = SHARED.findTopLevelWidget(GuiBuildSettings)
|
||||
assert isinstance(bSettings, GuiBuildSettings)
|
||||
build = None
|
||||
@@ -147,7 +156,6 @@ def testManuscript_Builds(qtbot: QtBot, nwGUI: GuiMain, projPath: Path):
|
||||
# May have been garbage collected, but if it isn't, it should be hidden
|
||||
assert bSettings.isVisible() is False
|
||||
|
||||
# Finish
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testManuscript_Builds
|
||||
|
||||
Reference in New Issue
Block a user