Create subclasses for non-blocking dialogs
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)
|
||||
|
||||
@@ -33,8 +33,8 @@ from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
|
||||
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
|
||||
QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton, QSplitter,
|
||||
QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
|
||||
QLabel, QListWidget, QListWidgetItem, QPushButton, QSplitter,
|
||||
QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
@@ -47,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
|
||||
@@ -59,7 +59,7 @@ from novelwriter.types import (
|
||||
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
|
||||
@@ -74,8 +74,6 @@ class GuiManuscript(QDialog):
|
||||
|
||||
logger.debug("Create: GuiManuscript")
|
||||
self.setObjectName("GuiManuscript")
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
|
||||
self._builds = BuildCollection(SHARED.project)
|
||||
self._buildMap: dict[str, QListWidgetItem] = {}
|
||||
@@ -466,17 +464,13 @@ class GuiManuscript(QDialog):
|
||||
if isinstance(obj, GuiBuildSettings):
|
||||
if obj.buildID == build.buildID:
|
||||
logger.debug("Found instance of GuiBuildSettings")
|
||||
obj.show()
|
||||
obj.raise_()
|
||||
obj.activateDialog()
|
||||
return
|
||||
|
||||
dlgSettings = GuiBuildSettings(SHARED.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
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
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
|
||||
)
|
||||
@@ -40,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
|
||||
@@ -52,7 +54,7 @@ from novelwriter.types import (
|
||||
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,8 +74,6 @@ class GuiBuildSettings(QDialog):
|
||||
|
||||
logger.debug("Create: GuiBuildSettings")
|
||||
self.setObjectName("GuiBuildSettings")
|
||||
if CONFIG.osDarwin:
|
||||
self.setWindowFlag(Qt.WindowType.Tool)
|
||||
|
||||
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 = []
|
||||
|
||||
@@ -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
|
||||
@@ -127,8 +127,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 +149,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