Clean up code in preparation for Qt6 (#1792)
This commit is contained in:
@@ -187,7 +187,7 @@ def main(sysArgs: list | None = None):
|
||||
))
|
||||
for errLine in errorData:
|
||||
logger.critical(errLine)
|
||||
errApp.exec_()
|
||||
errApp.exec()
|
||||
sys.exit(errorCode)
|
||||
|
||||
# Finish initialising config
|
||||
@@ -237,6 +237,6 @@ def main(sysArgs: list | None = None):
|
||||
nwGUI = GuiMain()
|
||||
nwGUI.postLaunchTasks(cmdOpen)
|
||||
|
||||
sys.exit(nwApp.exec_())
|
||||
sys.exit(nwApp.exec())
|
||||
|
||||
# END Function main
|
||||
|
||||
@@ -61,8 +61,12 @@ class Config:
|
||||
self.appHandle = "novelwriter"
|
||||
|
||||
# Set Paths
|
||||
confRoot = Path(QStandardPaths.writableLocation(QStandardPaths.ConfigLocation))
|
||||
dataRoot = Path(QStandardPaths.writableLocation(QStandardPaths.AppDataLocation))
|
||||
confRoot = Path(QStandardPaths.writableLocation(
|
||||
QStandardPaths.StandardLocation.ConfigLocation)
|
||||
)
|
||||
dataRoot = Path(QStandardPaths.writableLocation(
|
||||
QStandardPaths.StandardLocation.AppDataLocation)
|
||||
)
|
||||
|
||||
self._confPath = confRoot.absolute() / self.appHandle # The user config location
|
||||
self._dataPath = dataRoot.absolute() / self.appHandle # The user data location
|
||||
@@ -83,7 +87,7 @@ class Config:
|
||||
# Localisation
|
||||
# Note that these paths must be strings
|
||||
self._nwLangPath = self._appPath / "assets" / "i18n"
|
||||
self._qtLangPath = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
||||
self._qtLangPath = QLibraryInfo.location(QLibraryInfo.LibraryLocation.TranslationsPath)
|
||||
|
||||
hasLocale = (self._nwLangPath / f"nw_{QLocale.system().name()}.qm").exists()
|
||||
self._qLocale = QLocale.system() if hasLocale else QLocale("en_GB")
|
||||
@@ -369,7 +373,7 @@ class Config:
|
||||
elif self.osDarwin and "Helvetica" in fontFam:
|
||||
self.textFont = "Helvetica"
|
||||
else:
|
||||
self.textFont = fontDB.systemFont(QFontDatabase.GeneralFont).family()
|
||||
self.textFont = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont).family()
|
||||
else:
|
||||
self.textFont = family
|
||||
return
|
||||
|
||||
@@ -35,6 +35,7 @@ from PyQt5.QtCore import QRectF
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.common import minmax, simplified
|
||||
from novelwriter.types import QtPaintAnitAlias, QtTransparent
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from typing import TypeGuard # Requires Python 3.10
|
||||
@@ -248,10 +249,10 @@ class NWStatus:
|
||||
def _createIcon(self, red: int, green: int, blue: int) -> QIcon:
|
||||
"""Generate an icon for a status label."""
|
||||
pixmap = QPixmap(self._iPX, self._iPX)
|
||||
pixmap.fill(QColor(0, 0, 0, 0))
|
||||
pixmap.fill(QtTransparent)
|
||||
|
||||
painter = QPainter(pixmap)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
painter.setRenderHint(QtPaintAnitAlias)
|
||||
painter.fillPath(self._iconPath, QColor(red, green, blue))
|
||||
painter.end()
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ from PyQt5.QtWidgets import (
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import readTextFile
|
||||
from novelwriter.common import cssCol, readTextFile
|
||||
from novelwriter.extensions.configlayout import NColourLabel
|
||||
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
||||
from novelwriter.types import QtAlignRightTop
|
||||
from novelwriter.types import QtAlignRightTop, QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -70,7 +70,7 @@ class GuiAbout(QDialog):
|
||||
|
||||
self.nwLicence = QLabel(self.tr("This application is licenced under {0}").format(
|
||||
"<a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a>"
|
||||
))
|
||||
), self)
|
||||
self.nwLicence.setOpenExternalLinks(True)
|
||||
|
||||
# Credits
|
||||
@@ -84,7 +84,7 @@ class GuiAbout(QDialog):
|
||||
self.txtCredits.setViewportMargins(0, hA, hA, 0)
|
||||
|
||||
# Buttons
|
||||
self.btnBox = QDialogButtonBox(QDialogButtonBox.Close, self)
|
||||
self.btnBox = QDialogButtonBox(QtDialogClose, self)
|
||||
self.btnBox.rejected.connect(self.close)
|
||||
|
||||
# Assemble
|
||||
@@ -147,10 +147,10 @@ class GuiAbout(QDialog):
|
||||
|
||||
def _setStyleSheet(self) -> None:
|
||||
"""Set stylesheet for all browser tabs."""
|
||||
baseCol = self.palette().window().color()
|
||||
self.txtCredits.setStyleSheet((
|
||||
"QTextBrowser {{border: none; background: rgb({r},{g},{b});}} "
|
||||
).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue()))
|
||||
baseCol = cssCol(self.palette().window().color())
|
||||
self.txtCredits.setStyleSheet(
|
||||
f"QTextBrowser {{border: none; background: {baseCol};}} "
|
||||
)
|
||||
return
|
||||
|
||||
# END Class GuiAbout
|
||||
|
||||
@@ -26,8 +26,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout, QLabel,
|
||||
QListWidget, QListWidgetItem, QVBoxLayout, QWidget
|
||||
@@ -36,13 +36,14 @@ from PyQt5.QtWidgets import (
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.extensions.configlayout import NColourLabel
|
||||
from novelwriter.types import QtDialogCancel, QtDialogOk, QtDialogReset, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiDocMerge(QDialog):
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_HANDLE = QtUserRole
|
||||
|
||||
def __init__(self, parent: QWidget, sHandle: str, itemList: list[str]) -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -53,7 +54,8 @@ class GuiDocMerge(QDialog):
|
||||
|
||||
self._data = {}
|
||||
|
||||
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Documents to Merge")))
|
||||
self.headLabel = QLabel(self.tr("Documents to Merge"), self)
|
||||
self.headLabel.setFont(SHARED.theme.guiFontB)
|
||||
self.helpLabel = NColourLabel(
|
||||
self.tr("Drag and drop items to change the order, or uncheck to exclude."),
|
||||
SHARED.theme.helpText, parent=self, wrap=True
|
||||
@@ -69,12 +71,12 @@ class GuiDocMerge(QDialog):
|
||||
self.listBox.setIconSize(iSz)
|
||||
self.listBox.setMinimumWidth(CONFIG.pxInt(400))
|
||||
self.listBox.setMinimumHeight(CONFIG.pxInt(180))
|
||||
self.listBox.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.listBox.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
self.listBox.setDragDropMode(QAbstractItemView.InternalMove)
|
||||
self.listBox.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||
self.listBox.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
|
||||
self.listBox.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
||||
|
||||
# Merge Options
|
||||
self.trashLabel = QLabel(self.tr("Move merged items to Trash"))
|
||||
self.trashLabel = QLabel(self.tr("Move merged items to Trash"), self)
|
||||
self.trashSwitch = NSwitch(self, height=iPx)
|
||||
|
||||
self.optBox = QGridLayout()
|
||||
@@ -84,11 +86,11 @@ class GuiDocMerge(QDialog):
|
||||
self.optBox.setColumnStretch(2, 1)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogOk | QtDialogCancel, self)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
self.resetButton = self.buttonBox.addButton(QDialogButtonBox.Reset)
|
||||
self.resetButton = self.buttonBox.addButton(QtDialogReset)
|
||||
self.resetButton.clicked.connect(self._resetList)
|
||||
|
||||
# Assemble
|
||||
@@ -120,7 +122,7 @@ class GuiDocMerge(QDialog):
|
||||
finalItems = []
|
||||
for i in range(self.listBox.count()):
|
||||
item = self.listBox.item(i)
|
||||
if item is not None and item.checkState() == Qt.Checked:
|
||||
if item is not None and item.checkState() == Qt.CheckState.Checked:
|
||||
finalItems.append(item.data(self.D_HANDLE))
|
||||
|
||||
self._data["moveToTrash"] = self.trashSwitch.isChecked()
|
||||
@@ -175,7 +177,7 @@ class GuiDocMerge(QDialog):
|
||||
newItem.setIcon(itemIcon)
|
||||
newItem.setText(nwItem.itemName)
|
||||
newItem.setData(self.D_HANDLE, tHandle)
|
||||
newItem.setCheckState(Qt.Checked)
|
||||
newItem.setCheckState(Qt.CheckState.Checked)
|
||||
|
||||
self.listBox.addItem(newItem)
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QComboBox, QDialog, QDialogButtonBox, QGridLayout,
|
||||
QLabel, QListWidget, QListWidgetItem, QVBoxLayout, QWidget
|
||||
@@ -36,15 +36,16 @@ from PyQt5.QtWidgets import (
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.extensions.configlayout import NColourLabel
|
||||
from novelwriter.types import QtDialogCancel, QtDialogOk, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuiDocSplit(QDialog):
|
||||
|
||||
LINE_ROLE = Qt.ItemDataRole.UserRole
|
||||
LEVEL_ROLE = Qt.ItemDataRole.UserRole + 1
|
||||
LABEL_ROLE = Qt.ItemDataRole.UserRole + 2
|
||||
LINE_ROLE = QtUserRole
|
||||
LEVEL_ROLE = QtUserRole + 1
|
||||
LABEL_ROLE = QtUserRole + 2
|
||||
|
||||
def __init__(self, parent: QWidget, sHandle: str) -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -57,7 +58,8 @@ class GuiDocSplit(QDialog):
|
||||
|
||||
self.setWindowTitle(self.tr("Split Document"))
|
||||
|
||||
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headings")))
|
||||
self.headLabel = QLabel(self.tr("Document Headings"), self)
|
||||
self.headLabel.setFont(SHARED.theme.guiFontB)
|
||||
self.helpLabel = NColourLabel(
|
||||
self.tr("Select the maximum level to split into files."),
|
||||
SHARED.theme.helpText, parent=self, wrap=True
|
||||
@@ -75,8 +77,8 @@ class GuiDocSplit(QDialog):
|
||||
docHierarchy = pOptions.getBool("GuiDocSplit", "docHierarchy", True)
|
||||
|
||||
# Heading Selection
|
||||
self.listBox = QListWidget()
|
||||
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
|
||||
self.listBox = QListWidget(self)
|
||||
self.listBox.setDragDropMode(QAbstractItemView.DragDropMode.NoDragDrop)
|
||||
self.listBox.setMinimumWidth(CONFIG.pxInt(400))
|
||||
self.listBox.setMinimumHeight(CONFIG.pxInt(180))
|
||||
|
||||
@@ -91,15 +93,15 @@ class GuiDocSplit(QDialog):
|
||||
self.splitLevel.currentIndexChanged.connect(self._reloadList)
|
||||
|
||||
# Split Options
|
||||
self.folderLabel = QLabel(self.tr("Split into a new folder"))
|
||||
self.folderLabel = QLabel(self.tr("Split into a new folder"), self)
|
||||
self.folderSwitch = NSwitch(self, height=iPx)
|
||||
self.folderSwitch.setChecked(intoFolder)
|
||||
|
||||
self.hierarchyLabel = QLabel(self.tr("Create document hierarchy"))
|
||||
self.hierarchyLabel = QLabel(self.tr("Create document hierarchy"), self)
|
||||
self.hierarchySwitch = NSwitch(self, height=iPx)
|
||||
self.hierarchySwitch.setChecked(docHierarchy)
|
||||
|
||||
self.trashLabel = QLabel(self.tr("Move split document to Trash"))
|
||||
self.trashLabel = QLabel(self.tr("Move split document to Trash"), self)
|
||||
self.trashSwitch = NSwitch(self, height=iPx)
|
||||
|
||||
self.optBox = QGridLayout()
|
||||
@@ -114,7 +116,7 @@ class GuiDocSplit(QDialog):
|
||||
self.optBox.setColumnStretch(3, 1)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogOk | QtDialogCancel, self)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ from PyQt5.QtWidgets import (
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.types import QtDialogCancel, QtDialogOk
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -55,13 +56,13 @@ class GuiEditLabel(QDialog):
|
||||
self.labelValue.selectAll()
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogOk | QtDialogCancel, self)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
# Assemble
|
||||
self.innerBox = QHBoxLayout()
|
||||
self.innerBox.addWidget(QLabel(self.tr("Label")), 0)
|
||||
self.innerBox.addWidget(QLabel(self.tr("Label"), self), 0)
|
||||
self.innerBox.addWidget(self.labelValue, 1)
|
||||
self.innerBox.setSpacing(mSp)
|
||||
|
||||
@@ -88,9 +89,9 @@ class GuiEditLabel(QDialog):
|
||||
def getLabel(cls, parent: QWidget, text: str) -> tuple[str, bool]:
|
||||
"""Pop the dialog and return the result."""
|
||||
cls = GuiEditLabel(parent, text=text)
|
||||
cls.exec_()
|
||||
cls.exec()
|
||||
label = cls.itemLabel
|
||||
accepted = cls.result() == QDialog.Accepted
|
||||
accepted = cls.result() == QDialog.DialogCode.Accepted
|
||||
cls.deleteLater()
|
||||
return label, accepted
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractButton, QCompleter, QDialog, QDialogButtonBox, QFileDialog,
|
||||
QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget,
|
||||
qApp
|
||||
QAbstractButton, QApplication, QCompleter, QDialog, QDialogButtonBox,
|
||||
QFileDialog, QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout,
|
||||
QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -41,7 +41,10 @@ from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
|
||||
from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import QtAlignCenter
|
||||
from novelwriter.types import (
|
||||
QtAlignCenter, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept,
|
||||
QtRoleApply, QtRoleReject
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -84,11 +87,7 @@ class GuiPreferences(QDialog):
|
||||
self.mainForm.setHelpTextStyle(SHARED.theme.helpText)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(
|
||||
QDialogButtonBox.StandardButton.Apply
|
||||
| QDialogButtonBox.StandardButton.Save
|
||||
| QDialogButtonBox.StandardButton.Close
|
||||
)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogApply | QtDialogSave | QtDialogClose, self)
|
||||
self.buttonBox.clicked.connect(self._dialogButtonClicked)
|
||||
|
||||
# Assemble
|
||||
@@ -742,7 +741,7 @@ class GuiPreferences(QDialog):
|
||||
logger.debug("Close: GuiPreferences")
|
||||
self._saveWindowSize()
|
||||
event.accept()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.done(nwConst.DLG_FINISHED)
|
||||
self.deleteLater()
|
||||
return
|
||||
@@ -762,12 +761,12 @@ class GuiPreferences(QDialog):
|
||||
def _dialogButtonClicked(self, button: QAbstractButton) -> None:
|
||||
"""Handle button clicks from the dialog button box."""
|
||||
role = self.buttonBox.buttonRole(button)
|
||||
if role == QDialogButtonBox.ButtonRole.ApplyRole:
|
||||
if role == QtRoleApply:
|
||||
self._saveValues()
|
||||
elif role == QDialogButtonBox.ButtonRole.AcceptRole:
|
||||
elif role == QtRoleAccept:
|
||||
self._saveValues()
|
||||
self.close()
|
||||
elif role == QDialogButtonBox.ButtonRole.RejectRole:
|
||||
elif role == QtRoleReject:
|
||||
self.close()
|
||||
return
|
||||
|
||||
@@ -812,7 +811,7 @@ class GuiPreferences(QDialog):
|
||||
"""Open a dialog to select the backup folder."""
|
||||
if path := QFileDialog.getExistingDirectory(
|
||||
self, self.tr("Backup Directory"), str(self.backupPath) or "",
|
||||
options=QFileDialog.ShowDirsOnly
|
||||
options=QFileDialog.Option.ShowDirsOnly
|
||||
):
|
||||
self.backupPath = path
|
||||
self.mainForm.setHelpText("backupPath", self.tr("Path: {0}").format(path))
|
||||
|
||||
@@ -26,12 +26,12 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
|
||||
from PyQt5.QtWidgets import (
|
||||
QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout, QLineEdit,
|
||||
QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
|
||||
QWidget, qApp
|
||||
QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout,
|
||||
QLineEdit, QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -40,6 +40,7 @@ from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrol
|
||||
from novelwriter.extensions.modified import NComboBox, NIconToolButton
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import QtDialogCancel, QtDialogSave, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -83,9 +84,7 @@ class GuiProjectSettings(QDialog):
|
||||
self.sidebar.buttonClicked.connect(self._sidebarClicked)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(
|
||||
QDialogButtonBox.StandardButton.Save | QDialogButtonBox.StandardButton.Cancel
|
||||
)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogCancel, self)
|
||||
self.buttonBox.accepted.connect(self._doSave)
|
||||
self.buttonBox.rejected.connect(self.close)
|
||||
|
||||
@@ -195,7 +194,7 @@ class GuiProjectSettings(QDialog):
|
||||
project.data.setAutoReplace(newList)
|
||||
|
||||
self.newProjectSettingsReady.emit(rebuildTrees)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.close()
|
||||
|
||||
return
|
||||
@@ -305,9 +304,9 @@ class _StatusPage(NFixedPage):
|
||||
COL_LABEL = 0
|
||||
COL_USAGE = 1
|
||||
|
||||
KEY_ROLE = Qt.ItemDataRole.UserRole
|
||||
COL_ROLE = Qt.ItemDataRole.UserRole + 1
|
||||
NUM_ROLE = Qt.ItemDataRole.UserRole + 2
|
||||
KEY_ROLE = QtUserRole
|
||||
COL_ROLE = QtUserRole + 1
|
||||
NUM_ROLE = QtUserRole + 2
|
||||
|
||||
def __init__(self, parent: QWidget, isStatus: bool) -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -604,7 +603,7 @@ class _ReplacePage(NFixedPage):
|
||||
)
|
||||
|
||||
# List Box
|
||||
self.listBox = QTreeWidget()
|
||||
self.listBox = QTreeWidget(self)
|
||||
self.listBox.setHeaderLabels([self.tr("Keyword"), self.tr("Replace With")])
|
||||
self.listBox.setColumnWidth(self.COL_KEY, wCol0)
|
||||
self.listBox.setIndentation(0)
|
||||
@@ -614,7 +613,7 @@ class _ReplacePage(NFixedPage):
|
||||
newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
|
||||
self.listBox.addTopLevelItem(newItem)
|
||||
|
||||
self.listBox.sortByColumn(self.COL_KEY, Qt.AscendingOrder)
|
||||
self.listBox.sortByColumn(self.COL_KEY, Qt.SortOrder.AscendingOrder)
|
||||
self.listBox.setSortingEnabled(True)
|
||||
|
||||
# List Controls
|
||||
|
||||
@@ -26,7 +26,7 @@ from __future__ import annotations
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import QFontMetrics
|
||||
from PyQt5.QtCore import QSize, Qt, pyqtSlot
|
||||
from PyQt5.QtCore import QSize, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QDialogButtonBox, QFrame, QHBoxLayout, QLabel, QListWidget,
|
||||
QListWidgetItem, QVBoxLayout, QWidget
|
||||
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.constants import trConst, nwQuotes
|
||||
from novelwriter.types import QtAlignCenter, QtAlignTop
|
||||
from novelwriter.types import QtAlignCenter, QtAlignTop, QtDialogCancel, QtDialogOk, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,7 +43,7 @@ class GuiQuoteSelect(QDialog):
|
||||
|
||||
_selected = ""
|
||||
|
||||
D_KEY = Qt.ItemDataRole.UserRole
|
||||
D_KEY = QtUserRole
|
||||
|
||||
def __init__(self, parent: QWidget, current: str = '"') -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -66,14 +66,14 @@ class GuiQuoteSelect(QDialog):
|
||||
lblFont.setPointSizeF(4*lblFont.pointSizeF())
|
||||
|
||||
# Preview Label
|
||||
self.previewLabel = QLabel(current)
|
||||
self.previewLabel = QLabel(current, self)
|
||||
self.previewLabel.setFont(lblFont)
|
||||
self.previewLabel.setFixedSize(QSize(pxW, pxH))
|
||||
self.previewLabel.setAlignment(QtAlignCenter)
|
||||
self.previewLabel.setFrameStyle(QFrame.Box | QFrame.Plain)
|
||||
self.previewLabel.setFrameStyle(QFrame.Shape.Box | QFrame.Shadow.Plain)
|
||||
|
||||
# Quote Symbols
|
||||
self.listBox = QListWidget()
|
||||
self.listBox = QListWidget(self)
|
||||
self.listBox.itemSelectionChanged.connect(self._selectedSymbol)
|
||||
|
||||
minSize = 100
|
||||
@@ -90,7 +90,7 @@ class GuiQuoteSelect(QDialog):
|
||||
self.listBox.setMinimumHeight(CONFIG.pxInt(150))
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogOk | QtDialogCancel, self)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
@@ -123,7 +123,7 @@ class GuiQuoteSelect(QDialog):
|
||||
def getQuote(cls, parent: QWidget, current: str = "") -> tuple[str, bool]:
|
||||
"""Pop the dialog and return the result."""
|
||||
cls = GuiQuoteSelect(parent, current=current)
|
||||
cls.exec_()
|
||||
cls.exec()
|
||||
quote = cls._selected
|
||||
accepted = cls.result() == QDialog.DialogCode.Accepted
|
||||
cls.deleteLater()
|
||||
|
||||
@@ -28,11 +28,11 @@ import logging
|
||||
from typing import TYPE_CHECKING
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog, QHBoxLayout,
|
||||
QLineEdit, QListWidget, QVBoxLayout, qApp
|
||||
QAbstractItemView, QApplication, QDialog, QDialogButtonBox, QFileDialog,
|
||||
QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -40,6 +40,7 @@ from novelwriter.common import formatFileFilter
|
||||
from novelwriter.core.spellcheck import UserDictionary
|
||||
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
|
||||
@@ -91,7 +92,7 @@ class GuiWordList(QDialog):
|
||||
|
||||
# List Box
|
||||
self.listBox = QListWidget(self)
|
||||
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
|
||||
self.listBox.setDragDropMode(QAbstractItemView.DragDropMode.NoDragDrop)
|
||||
self.listBox.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||
self.listBox.setSortingEnabled(True)
|
||||
|
||||
@@ -110,7 +111,7 @@ class GuiWordList(QDialog):
|
||||
self.editBox.addWidget(self.delButton, 0)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogClose, self)
|
||||
self.buttonBox.accepted.connect(self._doSave)
|
||||
self.buttonBox.rejected.connect(self.close)
|
||||
|
||||
@@ -157,7 +158,7 @@ class GuiWordList(QDialog):
|
||||
self.newEntry.setText("")
|
||||
self.listBox.clearSelection()
|
||||
self._addWord(word)
|
||||
if items := self.listBox.findItems(word, Qt.MatchExactly):
|
||||
if items := self.listBox.findItems(word, Qt.MatchFlag.MatchExactly):
|
||||
self.listBox.setCurrentItem(items[0])
|
||||
self.listBox.scrollToItem(items[0], QAbstractItemView.ScrollHint.PositionAtCenter)
|
||||
return
|
||||
@@ -177,7 +178,7 @@ class GuiWordList(QDialog):
|
||||
userDict.add(word)
|
||||
userDict.save()
|
||||
self.newWordListReady.emit()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.close()
|
||||
return
|
||||
|
||||
@@ -244,7 +245,7 @@ class GuiWordList(QDialog):
|
||||
|
||||
def _addWord(self, word: str) -> None:
|
||||
"""Add a single word to the list."""
|
||||
if word and not self.listBox.findItems(word, Qt.MatchExactly):
|
||||
if word and not self.listBox.findItems(word, Qt.MatchFlag.MatchExactly):
|
||||
self.listBox.addItem(word)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
+11
-9
@@ -29,11 +29,11 @@ import logging
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtGui import QFont, QFontDatabase
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtGui import QFont, QFontDatabase
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget, qApp, QDialog, QGridLayout, QStyle, QPlainTextEdit, QLabel,
|
||||
QDialogButtonBox
|
||||
QApplication, QWidget, QDialog, QGridLayout, QStyle, QPlainTextEdit,
|
||||
QLabel, QDialogButtonBox
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
@@ -74,7 +74,9 @@ class NWErrorMessage(QDialog):
|
||||
# Widgets
|
||||
self.msgIcon = QLabel()
|
||||
self.msgIcon.setPixmap(
|
||||
qApp.style().standardIcon(QStyle.SP_MessageBoxCritical).pixmap(64, 64)
|
||||
QApplication.style().standardIcon(
|
||||
QStyle.StandardPixmap.SP_MessageBoxCritical
|
||||
).pixmap(64, 64)
|
||||
)
|
||||
self.msgHead = QLabel()
|
||||
self.msgHead.setOpenExternalLinks(True)
|
||||
@@ -88,7 +90,7 @@ class NWErrorMessage(QDialog):
|
||||
self.msgBody.setFont(font)
|
||||
self.msgBody.setReadOnly(True)
|
||||
|
||||
self.btnBox = QDialogButtonBox(QDialogButtonBox.Close)
|
||||
self.btnBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
|
||||
self.btnBox.rejected.connect(self._doClose)
|
||||
|
||||
# Assemble
|
||||
@@ -179,14 +181,14 @@ class NWErrorMessage(QDialog):
|
||||
def exceptionHandler(exType: type, exValue: BaseException, exTrace: TracebackType) -> None:
|
||||
"""Function to catch unhandled global exceptions."""
|
||||
from traceback import print_tb
|
||||
from PyQt5.QtWidgets import qApp
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
logger.critical("%s: %s", exType.__name__, str(exValue))
|
||||
print_tb(exTrace)
|
||||
|
||||
try:
|
||||
nwGUI = None
|
||||
for qWin in qApp.topLevelWidgets():
|
||||
for qWin in QApplication.topLevelWidgets():
|
||||
if qWin.objectName() == "GuiMain":
|
||||
nwGUI = qWin
|
||||
break
|
||||
@@ -197,7 +199,7 @@ def exceptionHandler(exType: type, exValue: BaseException, exTrace: TracebackTyp
|
||||
|
||||
errMsg = NWErrorMessage(nwGUI)
|
||||
errMsg.setMessage(exType, exValue, exTrace)
|
||||
errMsg.exec_()
|
||||
errMsg.exec()
|
||||
|
||||
try:
|
||||
# Try a controlled shutdown
|
||||
@@ -209,7 +211,7 @@ def exceptionHandler(exType: type, exValue: BaseException, exTrace: TracebackTyp
|
||||
logger.critical("Could not close the project before exiting")
|
||||
logger.critical(formatException(exc))
|
||||
|
||||
qApp.exit(1)
|
||||
QApplication.exit(1)
|
||||
|
||||
except Exception as exc:
|
||||
logger.critical(formatException(exc))
|
||||
|
||||
@@ -25,11 +25,13 @@ from __future__ import annotations
|
||||
|
||||
from math import ceil
|
||||
|
||||
from PyQt5.QtCore import QRect
|
||||
from PyQt5.QtGui import QBrush, QColor, QPaintEvent, QPainter, QPen
|
||||
from PyQt5.QtCore import QRect, Qt
|
||||
from PyQt5.QtWidgets import QProgressBar, QSizePolicy, QWidget
|
||||
|
||||
from novelwriter.types import QtAlignCenter
|
||||
from novelwriter.types import (
|
||||
QtPaintAnitAlias, QtAlignCenter, QtRoundCap, QtSolidLine, QtTransparent
|
||||
)
|
||||
|
||||
|
||||
class NProgressCircle(QProgressBar):
|
||||
@@ -50,14 +52,14 @@ class NProgressCircle(QProgressBar):
|
||||
self._point = point
|
||||
self._dRect = QRect(0, 0, size, size)
|
||||
self._cRect = QRect(point, point, size - 2*point, size - 2*point)
|
||||
self._dPen = QPen(Qt.transparent)
|
||||
self._dBrush = QBrush(Qt.transparent)
|
||||
self._dPen = QPen(QtTransparent)
|
||||
self._dBrush = QBrush(QtTransparent)
|
||||
self.setColours(
|
||||
track=self.palette().alternateBase().color(),
|
||||
bar=self.palette().highlight().color(),
|
||||
text=self.palette().text().color()
|
||||
)
|
||||
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
self.setFixedWidth(size)
|
||||
self.setFixedHeight(size)
|
||||
return
|
||||
@@ -69,9 +71,9 @@ class NProgressCircle(QProgressBar):
|
||||
self._dPen = QPen(back)
|
||||
self._dBrush = QBrush(back)
|
||||
if isinstance(bar, QColor):
|
||||
self._cPen = QPen(QBrush(bar), self._point, Qt.SolidLine, Qt.RoundCap)
|
||||
self._cPen = QPen(QBrush(bar), self._point, QtSolidLine, QtRoundCap)
|
||||
if isinstance(track, QColor):
|
||||
self._bPen = QPen(QBrush(track), self._point, Qt.SolidLine, Qt.RoundCap)
|
||||
self._bPen = QPen(QBrush(track), self._point, QtSolidLine, QtRoundCap)
|
||||
if isinstance(text, QColor):
|
||||
self._tColor = text
|
||||
return
|
||||
@@ -87,7 +89,7 @@ class NProgressCircle(QProgressBar):
|
||||
progress = 100.0*self.value()/self.maximum()
|
||||
angle = ceil(16*3.6*progress)
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||
painter.setRenderHint(QtPaintAnitAlias, True)
|
||||
painter.setPen(self._dPen)
|
||||
painter.setBrush(self._dBrush)
|
||||
painter.drawEllipse(self._dRect)
|
||||
|
||||
@@ -258,7 +258,7 @@ class NColourLabel(QLabel):
|
||||
font.setWeight(QFont.Weight.Bold if bold else QFont.Weight.Normal)
|
||||
if color:
|
||||
colour = self.palette()
|
||||
colour.setColor(QPalette.WindowText, color)
|
||||
colour.setColor(QPalette.ColorRole.WindowText, color)
|
||||
self.setPalette(colour)
|
||||
|
||||
self.setFont(font)
|
||||
|
||||
@@ -32,7 +32,7 @@ from PyQt5.QtWidgets import (
|
||||
QStyleOptionToolButton, QToolBar, QToolButton, QWidget
|
||||
)
|
||||
|
||||
from novelwriter.types import QtAlignLeft
|
||||
from novelwriter.types import QtPaintAnitAlias, QtAlignLeft, QtMouseOver, QtNoBrush, QtNoPen
|
||||
|
||||
|
||||
class NPagedSideBar(QToolBar):
|
||||
@@ -56,10 +56,10 @@ class NPagedSideBar(QToolBar):
|
||||
self._group.buttonClicked.connect(self._buttonClicked)
|
||||
|
||||
self.setMovable(False)
|
||||
self.setOrientation(Qt.Vertical)
|
||||
self.setOrientation(Qt.Orientation.Vertical)
|
||||
|
||||
stretch = QWidget(self)
|
||||
stretch.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
stretch.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
self._stretchAction = self.addWidget(stretch)
|
||||
|
||||
return
|
||||
@@ -119,13 +119,13 @@ class _NPagedToolButton(QToolButton):
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
self.setCheckable(True)
|
||||
|
||||
fH = self.fontMetrics().height()
|
||||
self._bH = round(fH * 1.7)
|
||||
self._tM = (self._bH - fH)//2
|
||||
self._lM = 3*self.style().pixelMetric(QStyle.PM_ButtonMargin)//2
|
||||
self._lM = 3*self.style().pixelMetric(QStyle.PixelMetric.PM_ButtonMargin)//2
|
||||
self._cR = self._lM//2
|
||||
self._aH = 2*fH//7
|
||||
self.setFixedHeight(self._bH)
|
||||
@@ -145,15 +145,15 @@ class _NPagedToolButton(QToolButton):
|
||||
opt.initFrom(self)
|
||||
|
||||
paint = QPainter(self)
|
||||
paint.setRenderHint(QPainter.Antialiasing, True)
|
||||
paint.setPen(Qt.NoPen)
|
||||
paint.setBrush(Qt.NoBrush)
|
||||
paint.setRenderHint(QtPaintAnitAlias, True)
|
||||
paint.setPen(QtNoPen)
|
||||
paint.setBrush(QtNoBrush)
|
||||
|
||||
width = self.width()
|
||||
height = self.height()
|
||||
palette = self.palette()
|
||||
|
||||
if opt.state & QStyle.State_MouseOver == QStyle.State_MouseOver:
|
||||
if opt.state & QtMouseOver == QtMouseOver:
|
||||
backCol = palette.base()
|
||||
paint.setBrush(backCol)
|
||||
paint.setOpacity(0.75)
|
||||
@@ -197,12 +197,12 @@ class _NPagedToolLabel(QLabel):
|
||||
def __init__(self, parent: QWidget, textColor: QColor | None = None) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
|
||||
fH = self.fontMetrics().height()
|
||||
self._bH = round(fH * 1.7)
|
||||
self._tM = (self._bH - fH)//2
|
||||
self._lM = self.style().pixelMetric(QStyle.PM_ButtonMargin)//2
|
||||
self._lM = self.style().pixelMetric(QStyle.PixelMetric.PM_ButtonMargin)//2
|
||||
self.setFixedHeight(self._bH)
|
||||
|
||||
self._textCol = textColor or self.palette().text().color()
|
||||
@@ -214,8 +214,8 @@ class _NPagedToolLabel(QLabel):
|
||||
label that matches the button style.
|
||||
"""
|
||||
paint = QPainter(self)
|
||||
paint.setRenderHint(QPainter.Antialiasing, True)
|
||||
paint.setPen(Qt.NoPen)
|
||||
paint.setRenderHint(QtPaintAnitAlias, True)
|
||||
paint.setPen(QtNoPen)
|
||||
|
||||
width = self.width()
|
||||
height = self.height()
|
||||
|
||||
@@ -28,6 +28,8 @@ from math import ceil
|
||||
from PyQt5.QtGui import QPaintEvent, QPainter
|
||||
from PyQt5.QtWidgets import QProgressBar, QWidget
|
||||
|
||||
from novelwriter.types import QtPaintAnitAlias
|
||||
|
||||
|
||||
class NProgressSimple(QProgressBar):
|
||||
"""Extension: Simple Progress Widget
|
||||
@@ -44,7 +46,7 @@ class NProgressSimple(QProgressBar):
|
||||
if (value := self.value()) > 0:
|
||||
progress = ceil(self.width()*float(value)/self.maximum())
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||
painter.setRenderHint(QtPaintAnitAlias, True)
|
||||
painter.setPen(self.palette().highlight().color())
|
||||
painter.setBrush(self.palette().highlight())
|
||||
painter.drawRect(0, 0, progress, self.height())
|
||||
|
||||
@@ -30,6 +30,8 @@ from typing import Literal
|
||||
from PyQt5.QtGui import QColor, QPaintEvent, QPainter
|
||||
from PyQt5.QtWidgets import QAbstractButton, QWidget
|
||||
|
||||
from novelwriter.types import QtPaintAnitAlias
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -67,7 +69,7 @@ class StatusLED(QAbstractButton):
|
||||
def paintEvent(self, event: QPaintEvent) -> None:
|
||||
"""Draw the LED."""
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||
painter.setRenderHint(QtPaintAnitAlias, True)
|
||||
painter.setPen(self.palette().dark().color())
|
||||
painter.setBrush(self._theCol)
|
||||
painter.setOpacity(1.0)
|
||||
|
||||
@@ -28,6 +28,7 @@ from PyQt5.QtCore import QEvent, QPropertyAnimation, Qt, pyqtProperty
|
||||
from PyQt5.QtWidgets import QAbstractButton, QSizePolicy, QWidget
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.types import QtPaintAnitAlias, QtMouseLeft, QtNoPen
|
||||
|
||||
|
||||
class NSwitch(QAbstractButton):
|
||||
@@ -45,7 +46,7 @@ class NSwitch(QAbstractButton):
|
||||
self._rR = self._xR - self._rB
|
||||
|
||||
self.setCheckable(True)
|
||||
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
self.setFixedWidth(self._xW)
|
||||
self.setFixedHeight(self._xH)
|
||||
self._offset = self._xR
|
||||
@@ -89,8 +90,8 @@ class NSwitch(QAbstractButton):
|
||||
def paintEvent(self, event: QPaintEvent) -> None:
|
||||
"""Drawing the switch itself."""
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||
painter.setPen(Qt.NoPen)
|
||||
painter.setRenderHint(QtPaintAnitAlias, True)
|
||||
painter.setPen(QtNoPen)
|
||||
|
||||
palette = self.palette()
|
||||
if self.isChecked():
|
||||
@@ -119,7 +120,7 @@ class NSwitch(QAbstractButton):
|
||||
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
|
||||
"""Animate the switch on mouse release."""
|
||||
super().mouseReleaseEvent(event)
|
||||
if event.button() == Qt.LeftButton:
|
||||
if event.button() == QtMouseLeft:
|
||||
anim = QPropertyAnimation(self, b"offset", self)
|
||||
anim.setDuration(120)
|
||||
anim.setStartValue(self._offset)
|
||||
@@ -129,7 +130,7 @@ class NSwitch(QAbstractButton):
|
||||
|
||||
def enterEvent(self, event: QEvent) -> None:
|
||||
"""Change the cursor when hovering the button."""
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
super().enterEvent(event)
|
||||
return
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ class NSwitchBox(QScrollArea):
|
||||
self._content = QGridLayout()
|
||||
self._content.setColumnStretch(1, 1)
|
||||
|
||||
self._widget = QWidget()
|
||||
self._widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
|
||||
self._widget = QWidget(self)
|
||||
self._widget.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Minimum)
|
||||
self._widget.setLayout(self._content)
|
||||
|
||||
self.setWidgetResizable(True)
|
||||
@@ -69,7 +69,7 @@ class NSwitchBox(QScrollArea):
|
||||
|
||||
def addLabel(self, text: str) -> None:
|
||||
"""Add a header label to the content box."""
|
||||
label = QLabel(text)
|
||||
label = QLabel(text, self)
|
||||
font = label.font()
|
||||
font.setBold(True)
|
||||
label.setFont(font)
|
||||
@@ -80,12 +80,12 @@ class NSwitchBox(QScrollArea):
|
||||
|
||||
def addItem(self, qIcon: QIcon, text: str, identifier: str, default: bool = False) -> None:
|
||||
"""Add an item to the content box."""
|
||||
icon = QLabel("")
|
||||
icon = QLabel("", self)
|
||||
icon.setAlignment(QtAlignRightMiddle)
|
||||
icon.setPixmap(qIcon.pixmap(self._sIcon, self._sIcon))
|
||||
self._content.addWidget(icon, self._index, 0, QtAlignLeft)
|
||||
|
||||
label = QLabel(text)
|
||||
label = QLabel(text, self)
|
||||
self._content.addWidget(label, self._index, 1, QtAlignLeft)
|
||||
|
||||
switch = NSwitch(self, height=self._hSwitch)
|
||||
@@ -100,7 +100,7 @@ class NSwitchBox(QScrollArea):
|
||||
|
||||
def addSeparator(self) -> None:
|
||||
"""Add a blank entry in the content box."""
|
||||
spacer = QWidget()
|
||||
spacer = QWidget(self)
|
||||
spacer.setFixedHeight(int(0.5*self._sIcon))
|
||||
self._content.addWidget(spacer, self._index, 0, 1, 3, QtAlignLeft)
|
||||
self._widgets.append(spacer)
|
||||
|
||||
@@ -47,8 +47,8 @@ from PyQt5.QtGui import (
|
||||
QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
|
||||
QPlainTextEdit, QShortcut, QToolBar, QVBoxLayout, QWidget, qApp
|
||||
QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QMenu, QPlainTextEdit, QShortcut, QToolBar, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -64,7 +64,9 @@ from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.text.counting import standardCounter
|
||||
from novelwriter.tools.lipsum import GuiLipsum
|
||||
from novelwriter.types import (
|
||||
QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop, QtAlignRight
|
||||
QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop,
|
||||
QtAlignRight, QtKeepAnchor, QtModCtrl, QtMouseLeft, QtModeNone, QtModShift,
|
||||
QtMoveAnchor, QtMoveLeft, QtMoveRight
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
@@ -181,12 +183,12 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self.keyContext.activated.connect(self._openContextFromCursor)
|
||||
|
||||
self.followTag1 = QShortcut(self)
|
||||
self.followTag1.setKey(Qt.Key.Key_Return | Qt.KeyboardModifier.ControlModifier)
|
||||
self.followTag1.setKey(Qt.Key.Key_Return | QtModCtrl)
|
||||
self.followTag1.setContext(Qt.ShortcutContext.WidgetShortcut)
|
||||
self.followTag1.activated.connect(self._processTag)
|
||||
|
||||
self.followTag2 = QShortcut(self)
|
||||
self.followTag2.setKey(Qt.Key.Key_Enter | Qt.KeyboardModifier.ControlModifier)
|
||||
self.followTag2.setKey(Qt.Key.Key_Enter | QtModCtrl)
|
||||
self.followTag2.setContext(Qt.ShortcutContext.WidgetShortcut)
|
||||
self.followTag2.activated.connect(self._processTag)
|
||||
|
||||
@@ -393,13 +395,13 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self.clearEditor()
|
||||
return False
|
||||
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
self._docHandle = tHandle
|
||||
|
||||
self._allowAutoReplace(False)
|
||||
self._qDocument.setTextContent(docText, tHandle)
|
||||
self._allowAutoReplace(True)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
|
||||
self._lastEdit = time()
|
||||
self._lastActive = time()
|
||||
@@ -423,12 +425,12 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self.setPlainText("")
|
||||
self.setCursorPosition(0)
|
||||
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.setDocumentChanged(False)
|
||||
self._qDocument.clearUndoRedoStacks()
|
||||
self.docToolBar.setVisible(CONFIG.showEditToolBar)
|
||||
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
# Update the status bar
|
||||
if self._nwItem is not None:
|
||||
@@ -445,11 +447,11 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
"""Replace the text of the current document with the provided
|
||||
text. This also clears undo history.
|
||||
"""
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
self.setPlainText(text)
|
||||
self.updateDocMargins()
|
||||
self.setDocumentChanged(True)
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
return
|
||||
|
||||
def saveText(self) -> bool:
|
||||
@@ -536,7 +538,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
while self.cursorRect().bottom() > vH and count < 100000:
|
||||
vBar.setValue(vBar.value() + 1)
|
||||
count += 1
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
def updateDocMargins(self) -> None:
|
||||
@@ -655,8 +657,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
"""Make a text selection."""
|
||||
if start >= 0 and length > 0:
|
||||
cursor = self.textCursor()
|
||||
cursor.setPosition(start, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(start + length, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(start, QtMoveAnchor)
|
||||
cursor.setPosition(start + length, QtKeepAnchor)
|
||||
self.setTextCursor(cursor)
|
||||
return
|
||||
|
||||
@@ -699,9 +701,9 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
"""
|
||||
logger.debug("Running spell checker")
|
||||
start = time()
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
self._qDocument.syntaxHighlighter.rehighlight()
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
logger.debug("Document highlighted in %.3f ms", 1000*(time() - start))
|
||||
self.statusMessage.emit(self.tr("Spell check complete"))
|
||||
return
|
||||
@@ -814,7 +816,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
|
||||
def anyFocus(self) -> bool:
|
||||
"""Check if any widget or child widget has focus."""
|
||||
return self.hasFocus() or self.isAncestorOf(qApp.focusWidget())
|
||||
return self.hasFocus() or self.isAncestorOf(QApplication.focusWidget())
|
||||
|
||||
def revealLocation(self) -> None:
|
||||
"""Tell the user where on the file system the file in the editor
|
||||
@@ -962,7 +964,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
super().keyPressEvent(event)
|
||||
nPos = self.cursorRect().topLeft().y()
|
||||
kMod = event.modifiers()
|
||||
okMod = kMod in (Qt.KeyboardModifier.NoModifier, Qt.KeyboardModifier.ShiftModifier)
|
||||
okMod = kMod in (QtModeNone, QtModShift)
|
||||
okKey = event.key() not in self.MOVE_KEYS
|
||||
if nPos != cPos and okMod and okKey:
|
||||
mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height()
|
||||
@@ -991,7 +993,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
pressed, check if we're clicking on a tag, and trigger the
|
||||
follow tag function.
|
||||
"""
|
||||
if qApp.keyboardModifiers() == Qt.KeyboardModifier.ControlModifier:
|
||||
if QApplication.keyboardModifiers() == QtModCtrl:
|
||||
self._processTag(self.cursorForPosition(event.pos()))
|
||||
super().mouseReleaseEvent(event)
|
||||
return
|
||||
@@ -1091,8 +1093,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
block = cursor.block()
|
||||
if block.isValid():
|
||||
pos += block.position()
|
||||
cursor.setPosition(pos, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(pos + length, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(pos, QtMoveAnchor)
|
||||
cursor.setPosition(pos + length, QtKeepAnchor)
|
||||
cursor.insertText(text)
|
||||
self._completer.hide()
|
||||
return
|
||||
@@ -1152,9 +1154,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
block = pCursor.block()
|
||||
sCursor = self.textCursor()
|
||||
sCursor.setPosition(block.position() + cPos)
|
||||
sCursor.movePosition(
|
||||
QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, cLen
|
||||
)
|
||||
sCursor.movePosition(QtMoveRight, QtKeepAnchor, cLen)
|
||||
if suggest:
|
||||
ctxMenu.addSeparator()
|
||||
ctxMenu.addAction(self.tr("Spelling Suggestion(s)"))
|
||||
@@ -1171,7 +1171,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
action.triggered.connect(lambda: self._addWord(word, block))
|
||||
|
||||
# Execute the context menu
|
||||
ctxMenu.exec_(self.viewport().mapToGlobal(pos))
|
||||
ctxMenu.exec(self.viewport().mapToGlobal(pos))
|
||||
ctxMenu.deleteLater()
|
||||
|
||||
return
|
||||
@@ -1350,8 +1350,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
else:
|
||||
resIdx = 0 if doLoop else maxIdx
|
||||
|
||||
cursor.setPosition(resS[resIdx], QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(resE[resIdx], QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(resS[resIdx], QtMoveAnchor)
|
||||
cursor.setPosition(resE[resIdx], QtKeepAnchor)
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
self.docSearch.setResultCount(resIdx + 1, len(resS))
|
||||
@@ -1397,8 +1397,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
break
|
||||
|
||||
if hasSelection:
|
||||
cursor.setPosition(origA, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(origB, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(origA, QtMoveAnchor)
|
||||
cursor.setPosition(origB, QtKeepAnchor)
|
||||
else:
|
||||
cursor.setPosition(origA)
|
||||
|
||||
@@ -1501,8 +1501,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
if blockS != blockE:
|
||||
posE = blockS.position() + blockS.length() - 1
|
||||
cursor.clearSelection()
|
||||
cursor.setPosition(posS, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(posS, QtMoveAnchor)
|
||||
cursor.setPosition(posE, QtKeepAnchor)
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
numB = 0
|
||||
@@ -1579,8 +1579,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
if select == _SelectAction.MOVE_AFTER:
|
||||
cursor.setPosition(posE + len(before + after))
|
||||
elif select == _SelectAction.KEEP_SELECTION:
|
||||
cursor.setPosition(posE + len(before), QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(posS + len(before), QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(posE + len(before), QtMoveAnchor)
|
||||
cursor.setPosition(posS + len(before), QtKeepAnchor)
|
||||
elif select == _SelectAction.KEEP_POSITION:
|
||||
cursor.setPosition(posO + len(before))
|
||||
|
||||
@@ -1602,9 +1602,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self._allowAutoReplace(False)
|
||||
for posC in range(posS, posE+1):
|
||||
cursor.setPosition(posC)
|
||||
cursor.movePosition(
|
||||
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 2
|
||||
)
|
||||
cursor.movePosition(QtMoveLeft, QtKeepAnchor, 2)
|
||||
selText = cursor.selectedText()
|
||||
|
||||
nS = len(selText)
|
||||
@@ -1624,16 +1622,12 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
cursor.setPosition(posC)
|
||||
if pC in closeCheck:
|
||||
cursor.beginEditBlock()
|
||||
cursor.movePosition(
|
||||
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
|
||||
)
|
||||
cursor.movePosition(QtMoveLeft, QtKeepAnchor, 1)
|
||||
cursor.insertText(oQuote)
|
||||
cursor.endEditBlock()
|
||||
else:
|
||||
cursor.beginEditBlock()
|
||||
cursor.movePosition(
|
||||
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
|
||||
)
|
||||
cursor.movePosition(QtMoveLeft, QtKeepAnchor, 1)
|
||||
cursor.insertText(cQuote)
|
||||
cursor.endEditBlock()
|
||||
|
||||
@@ -1849,9 +1843,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
cursor.beginEditBlock()
|
||||
cursor.clearSelection()
|
||||
cursor.setPosition(rS)
|
||||
cursor.movePosition(
|
||||
QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, rE-rS
|
||||
)
|
||||
cursor.movePosition(QtMoveRight, QtKeepAnchor, rE-rS)
|
||||
cursor.insertText(cleanText.rstrip() + "\n")
|
||||
cursor.endEditBlock()
|
||||
|
||||
@@ -1912,7 +1904,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
).format(tag)):
|
||||
itemClass = nwKeyWords.KEY_CLASS.get(tBits[0], nwItemClass.NO_CLASS)
|
||||
self.requestNewNoteCreation.emit(tag, itemClass)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self._qDocument.syntaxHighlighter.rehighlightBlock(block)
|
||||
|
||||
return nwTrinary.POSITIVE if exist else nwTrinary.NEGATIVE
|
||||
@@ -2017,9 +2009,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
tInsert = tInsert + self._typPadChar
|
||||
|
||||
if nDelete > 0:
|
||||
cursor.movePosition(
|
||||
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, nDelete
|
||||
)
|
||||
cursor.movePosition(QtMoveLeft, QtKeepAnchor, nDelete)
|
||||
cursor.insertText(tInsert)
|
||||
|
||||
return
|
||||
@@ -2075,8 +2065,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
return cursor
|
||||
|
||||
cursor.clearSelection()
|
||||
cursor.setPosition(sPos, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(ePos, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(sPos, QtMoveAnchor)
|
||||
cursor.setPosition(ePos, QtKeepAnchor)
|
||||
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
@@ -2100,8 +2090,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
posE = cursor.selectionEnd()
|
||||
selTxt = cursor.selectedText()
|
||||
if selTxt.startswith(nwUnicode.U_PSEP):
|
||||
cursor.setPosition(posS+1, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(posS+1, QtMoveAnchor)
|
||||
cursor.setPosition(posE, QtKeepAnchor)
|
||||
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
@@ -2440,11 +2430,11 @@ class GuiDocEditSearch(QFrame):
|
||||
self.searchOpt.setIconSize(iSz)
|
||||
self.searchOpt.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.searchLabel = QLabel(self.tr("Search"))
|
||||
self.searchLabel = QLabel(self.tr("Search"), self)
|
||||
self.searchLabel.setFont(self.boxFont)
|
||||
self.searchLabel.setIndent(CONFIG.pxInt(6))
|
||||
|
||||
self.resultLabel = QLabel("?/?")
|
||||
self.resultLabel = QLabel("?/?", self)
|
||||
self.resultLabel.setFont(self.boxFont)
|
||||
self.resultLabel.setMinimumWidth(SHARED.theme.getTextWidth("?/?", self.boxFont))
|
||||
|
||||
@@ -2627,7 +2617,7 @@ class GuiDocEditSearch(QFrame):
|
||||
|
||||
def updateTheme(self) -> None:
|
||||
"""Update theme elements."""
|
||||
qPalette = qApp.palette()
|
||||
qPalette = QApplication.palette()
|
||||
self.setPalette(qPalette)
|
||||
self.searchBox.setPalette(qPalette)
|
||||
self.replaceBox.setPalette(qPalette)
|
||||
@@ -2713,9 +2703,7 @@ class GuiDocEditSearch(QFrame):
|
||||
@pyqtSlot()
|
||||
def _doSearch(self) -> None:
|
||||
"""Call the search action function for the document editor."""
|
||||
self.docEditor.findNext(goBack=(
|
||||
qApp.keyboardModifiers() == Qt.KeyboardModifier.ShiftModifier)
|
||||
)
|
||||
self.docEditor.findNext(goBack=(QApplication.keyboardModifiers() == QtModShift))
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -3002,7 +2990,7 @@ class GuiDocEditHeader(QWidget):
|
||||
"""Capture a click on the title and ensure that the item is
|
||||
selected in the project tree.
|
||||
"""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
if event.button() == QtMouseLeft:
|
||||
self.docEditor.requestProjectItemSelected.emit(self._docHandle or "", True)
|
||||
return
|
||||
|
||||
@@ -3048,7 +3036,7 @@ class GuiDocEditFooter(QWidget):
|
||||
self.statusIcon.setFixedHeight(iPx)
|
||||
self.statusIcon.setAlignment(QtAlignLeftTop)
|
||||
|
||||
self.statusText = QLabel(self.tr("Status"))
|
||||
self.statusText = QLabel(self.tr("Status"), self)
|
||||
self.statusText.setIndent(0)
|
||||
self.statusText.setMargin(0)
|
||||
self.statusText.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
@@ -116,7 +116,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
# Cache Spell Error Format
|
||||
self._spellErr = QTextCharFormat()
|
||||
self._spellErr.setUnderlineColor(SHARED.theme.colSpell)
|
||||
self._spellErr.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||
self._spellErr.setUnderlineStyle(QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
|
||||
|
||||
# Multiple or Trailing Spaces
|
||||
if CONFIG.showMultiSpaces:
|
||||
@@ -402,16 +402,16 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
if style is not None:
|
||||
styles = style.split(",")
|
||||
if "bold" in styles:
|
||||
charFormat.setFontWeight(QFont.Bold)
|
||||
charFormat.setFontWeight(QFont.Weight.Bold)
|
||||
if "italic" in styles:
|
||||
charFormat.setFontItalic(True)
|
||||
if "strike" in styles:
|
||||
charFormat.setFontStrikeOut(True)
|
||||
if "errline" in styles:
|
||||
charFormat.setUnderlineColor(SHARED.theme.colError)
|
||||
charFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||
charFormat.setUnderlineStyle(QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
|
||||
if "background" in styles and color is not None:
|
||||
charFormat.setBackground(QBrush(color, Qt.SolidPattern))
|
||||
charFormat.setBackground(QBrush(color, Qt.BrushStyle.SolidPattern))
|
||||
|
||||
if size is not None:
|
||||
charFormat.setFontPointSize(int(round(size*CONFIG.textSize)))
|
||||
|
||||
@@ -36,8 +36,8 @@ from PyQt5.QtGui import (
|
||||
QTextOption
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QAction, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser, QToolButton,
|
||||
QWidget, qApp
|
||||
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
|
||||
QToolButton, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -49,7 +49,9 @@ from novelwriter.error import logException
|
||||
from novelwriter.extensions.eventfilters import WheelEventFilter
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.types import QtAlignCenterTop, QtAlignJustify
|
||||
from novelwriter.types import (
|
||||
QtAlignCenterTop, QtAlignJustify, QtKeepAnchor, QtMouseLeft, QtMoveAnchor
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -195,7 +197,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
return False
|
||||
|
||||
logger.debug("Generating preview for item '%s'", tHandle)
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
|
||||
sPos = self.verticalScrollBar().value()
|
||||
aDoc = ToHtml(SHARED.project)
|
||||
@@ -217,7 +219,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
logger.error("Failed to generate preview for document with handle '%s'", tHandle)
|
||||
logException()
|
||||
self.setText(self.tr("An error occurred while generating the preview."))
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
return False
|
||||
|
||||
# Refresh the tab stops
|
||||
@@ -250,7 +252,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
# Since we change the content while it may still be rendering, we mark
|
||||
# the document dirty again to make sure it's re-rendered properly.
|
||||
self.redrawText()
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
self.documentLoaded.emit(tHandle)
|
||||
|
||||
return True
|
||||
@@ -410,7 +412,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
ctxMenu.addAction(mnuSelPara)
|
||||
|
||||
# Open the context menu
|
||||
ctxMenu.exec_(self.viewport().mapToGlobal(point))
|
||||
ctxMenu.exec(self.viewport().mapToGlobal(point))
|
||||
ctxMenu.deleteLater()
|
||||
|
||||
return
|
||||
@@ -452,8 +454,8 @@ class GuiDocViewer(QTextBrowser):
|
||||
posE = cursor.selectionEnd()
|
||||
selTxt = cursor.selectedText()
|
||||
if selTxt.startswith(nwUnicode.U_PSEP):
|
||||
cursor.setPosition(posS+1, QTextCursor.MoveMode.MoveAnchor)
|
||||
cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
|
||||
cursor.setPosition(posS+1, QtMoveAnchor)
|
||||
cursor.setPosition(posE, QtKeepAnchor)
|
||||
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
@@ -635,7 +637,7 @@ class GuiDocViewHeader(QWidget):
|
||||
self.setAutoFillBackground(True)
|
||||
|
||||
# Title Label
|
||||
self.itemTitle = QLabel()
|
||||
self.itemTitle = QLabel(self)
|
||||
self.itemTitle.setText("")
|
||||
self.itemTitle.setIndent(0)
|
||||
self.itemTitle.setMargin(0)
|
||||
@@ -826,7 +828,7 @@ class GuiDocViewHeader(QWidget):
|
||||
"""Capture a click on the title and ensure that the item is
|
||||
selected in the project tree.
|
||||
"""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
if event.button() == QtMouseLeft:
|
||||
self.docViewer.requestProjectItemSelected.emit(self._docHandle, True)
|
||||
return
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ from novelwriter.core.index import IndexHeading, IndexItem
|
||||
from novelwriter.enum import nwDocMode, nwItemClass
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.types import QtDecoration, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -232,7 +233,7 @@ class _ViewPanelBackRefs(QTreeWidget):
|
||||
C_VIEW = 2
|
||||
C_TITLE = 3
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_HANDLE = QtUserRole
|
||||
|
||||
def __init__(self, parent: GuiDocViewerPanel) -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -349,7 +350,7 @@ class _ViewPanelBackRefs(QTreeWidget):
|
||||
trItem.setToolTip(self.C_DOC, nwItem.itemName)
|
||||
trItem.setIcon(self.C_EDIT, self._editIcon)
|
||||
trItem.setIcon(self.C_VIEW, self._viewIcon)
|
||||
trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec)
|
||||
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
||||
trItem.setText(self.C_TITLE, hItem.title)
|
||||
trItem.setToolTip(self.C_TITLE, hItem.title)
|
||||
trItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
|
||||
@@ -374,7 +375,7 @@ class _ViewPanelKeyWords(QTreeWidget):
|
||||
C_TITLE = 5
|
||||
C_SHORT = 6
|
||||
|
||||
D_TAG = Qt.ItemDataRole.UserRole
|
||||
D_TAG = QtUserRole
|
||||
|
||||
def __init__(self, parent: GuiDocViewerPanel, itemClass: nwItemClass) -> None:
|
||||
super().__init__(parent=parent)
|
||||
@@ -468,7 +469,7 @@ class _ViewPanelKeyWords(QTreeWidget):
|
||||
trItem.setIcon(self.C_DOC, docIcon)
|
||||
trItem.setText(self.C_DOC, nwItem.itemName)
|
||||
trItem.setToolTip(self.C_DOC, nwItem.itemName)
|
||||
trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec)
|
||||
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
||||
trItem.setText(self.C_TITLE, hItem.title)
|
||||
trItem.setToolTip(self.C_TITLE, hItem.title)
|
||||
trItem.setText(self.C_SHORT, hItem.synopsis)
|
||||
|
||||
@@ -25,14 +25,14 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from time import time
|
||||
from collections.abc import Iterable
|
||||
from time import time
|
||||
|
||||
from PyQt5.QtGui import QTextBlock, QTextCursor, QTextDocument
|
||||
from PyQt5.QtCore import QObject, pyqtSlot
|
||||
from PyQt5.QtWidgets import QPlainTextDocumentLayout, qApp
|
||||
from novelwriter import SHARED
|
||||
from PyQt5.QtWidgets import QApplication, QPlainTextDocumentLayout
|
||||
|
||||
from novelwriter import SHARED
|
||||
from novelwriter.gui.dochighlight import GuiDocHighlighter, TextBlockData
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -86,7 +86,7 @@ class GuiTextDocument(QTextDocument):
|
||||
self.setUndoRedoEnabled(True)
|
||||
self.blockSignals(False)
|
||||
self._syntax.rehighlight()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
|
||||
tEnd = time()
|
||||
|
||||
|
||||
@@ -115,25 +115,25 @@ class GuiItemDetails(QWidget):
|
||||
self.cCountName.setFont(fntLabel)
|
||||
self.cCountName.setAlignment(QtAlignRight)
|
||||
|
||||
self.cCountData = QLabel("")
|
||||
self.cCountData = QLabel("", self)
|
||||
self.cCountData.setFont(fntValue)
|
||||
self.cCountData.setAlignment(QtAlignRight)
|
||||
|
||||
# Word Count
|
||||
self.wCountName = QLabel(" "+self.tr("Words"))
|
||||
self.wCountName = QLabel(" "+self.tr("Words"), self)
|
||||
self.wCountName.setFont(fntLabel)
|
||||
self.wCountName.setAlignment(QtAlignRight)
|
||||
|
||||
self.wCountData = QLabel("")
|
||||
self.wCountData = QLabel("", self)
|
||||
self.wCountData.setFont(fntValue)
|
||||
self.wCountData.setAlignment(QtAlignRight)
|
||||
|
||||
# Paragraph Count
|
||||
self.pCountName = QLabel(" "+self.tr("Paragraphs"))
|
||||
self.pCountName = QLabel(" "+self.tr("Paragraphs"), self)
|
||||
self.pCountName.setFont(fntLabel)
|
||||
self.pCountName.setAlignment(QtAlignRight)
|
||||
|
||||
self.pCountData = QLabel("")
|
||||
self.pCountData = QLabel("", self)
|
||||
self.pCountData.setFont(fntValue)
|
||||
self.pCountData.setAlignment(QtAlignRight)
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ from enum import Enum
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
|
||||
from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSlot, pyqtSignal
|
||||
from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
|
||||
QInputDialog, QMenu, QSizePolicy, QToolTip, QTreeWidget, QTreeWidgetItem,
|
||||
@@ -47,7 +47,7 @@ from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.extensions.novelselector import NovelSelector
|
||||
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.types import QtAlignRight
|
||||
from novelwriter.types import QtAlignRight, QtDecoration, QtMouseLeft, QtMouseMiddle, QtUserRole
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -364,10 +364,10 @@ class GuiNovelTree(QTreeWidget):
|
||||
C_EXTRA = 2
|
||||
C_MORE = 3
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_TITLE = Qt.ItemDataRole.UserRole + 1
|
||||
D_KEY = Qt.ItemDataRole.UserRole + 2
|
||||
D_EXTRA = Qt.ItemDataRole.UserRole + 3
|
||||
D_HANDLE = QtUserRole
|
||||
D_TITLE = QtUserRole + 1
|
||||
D_KEY = QtUserRole + 2
|
||||
D_EXTRA = QtUserRole + 3
|
||||
|
||||
def __init__(self, novelView: GuiNovelView) -> None:
|
||||
super().__init__(parent=novelView)
|
||||
@@ -583,12 +583,12 @@ class GuiNovelTree(QTreeWidget):
|
||||
"""
|
||||
super().mousePressEvent(event)
|
||||
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
if event.button() == QtMouseLeft:
|
||||
selItem = self.indexAt(event.pos())
|
||||
if not selItem.isValid():
|
||||
self.clearSelection()
|
||||
|
||||
elif event.button() == Qt.MouseButton.MiddleButton:
|
||||
elif event.button() == QtMouseMiddle:
|
||||
selItem = self.itemAt(event.pos())
|
||||
if not isinstance(selItem, QTreeWidgetItem):
|
||||
return
|
||||
@@ -697,11 +697,11 @@ class GuiNovelTree(QTreeWidget):
|
||||
iLevel = nwHeaders.H_LEVEL.get(idxItem.level, 0)
|
||||
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
||||
|
||||
trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec)
|
||||
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
||||
trItem.setText(self.C_TITLE, idxItem.title)
|
||||
trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
|
||||
trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
|
||||
trItem.setData(self.C_MORE, Qt.ItemDataRole.DecorationRole, self._pMore)
|
||||
trItem.setData(self.C_MORE, QtDecoration, self._pMore)
|
||||
|
||||
# Custom column
|
||||
mW = int(self._lastColSize * self.viewport().width())
|
||||
|
||||
+41
-39
@@ -48,7 +48,9 @@ from novelwriter.error import logException
|
||||
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
|
||||
from novelwriter.constants import nwHeaders, trConst, nwKeyWords, nwLabels
|
||||
from novelwriter.extensions.novelselector import NovelSelector
|
||||
from novelwriter.types import QtAlignLeftTop, QtAlignRight, QtAlignRightTop
|
||||
from novelwriter.types import (
|
||||
QtAlignLeftTop, QtAlignRight, QtAlignRightTop, QtDecoration, QtUserRole
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -68,7 +70,7 @@ class GuiOutlineView(QWidget):
|
||||
self.outlineBar = GuiOutlineToolBar(self)
|
||||
self.outlineBar.setEnabled(False)
|
||||
|
||||
self.splitOutline = QSplitter(Qt.Vertical)
|
||||
self.splitOutline = QSplitter(Qt.Orientation.Vertical, self)
|
||||
self.splitOutline.addWidget(self.outlineTree)
|
||||
self.splitOutline.addWidget(self.outlineData)
|
||||
self.splitOutline.setOpaqueResize(False)
|
||||
@@ -218,7 +220,7 @@ class GuiOutlineToolBar(QToolBar):
|
||||
stretch.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
|
||||
# Novel Selector
|
||||
self.novelLabel = QLabel(self.tr("Outline of"))
|
||||
self.novelLabel = QLabel(self.tr("Outline of"), self)
|
||||
self.novelLabel.setContentsMargins(0, 0, mPx, 0)
|
||||
|
||||
self.novelValue = NovelSelector(self)
|
||||
@@ -354,8 +356,8 @@ class GuiOutlineTree(QTreeWidget):
|
||||
nwOutline.SYNOP: False,
|
||||
}
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_TITLE = Qt.ItemDataRole.UserRole + 1
|
||||
D_HANDLE = QtUserRole
|
||||
D_TITLE = QtUserRole + 1
|
||||
|
||||
hiddenStateChanged = pyqtSignal()
|
||||
activeItemChanged = pyqtSignal(str, str)
|
||||
@@ -692,7 +694,7 @@ class GuiOutlineTree(QTreeWidget):
|
||||
trItem = QTreeWidgetItem()
|
||||
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
||||
|
||||
trItem.setData(self._colIdx[nwOutline.TITLE], Qt.ItemDataRole.DecorationRole, hDec)
|
||||
trItem.setData(self._colIdx[nwOutline.TITLE], QtDecoration, hDec)
|
||||
trItem.setText(self._colIdx[nwOutline.TITLE], novIdx.title)
|
||||
trItem.setData(self._colIdx[nwOutline.TITLE], self.D_HANDLE, tHandle)
|
||||
trItem.setData(self._colIdx[nwOutline.TITLE], self.D_TITLE, sTitle)
|
||||
@@ -801,12 +803,12 @@ class GuiOutlineDetails(QScrollArea):
|
||||
bFont = SHARED.theme.guiFontB
|
||||
|
||||
# Details Area
|
||||
self.titleLabel = QLabel(self.tr("Title"))
|
||||
self.fileLabel = QLabel(self.tr("Document"))
|
||||
self.itemLabel = QLabel(self.tr("Status"))
|
||||
self.titleValue = QLabel("")
|
||||
self.fileValue = QLabel("")
|
||||
self.itemValue = QLabel("")
|
||||
self.titleLabel = QLabel(self.tr("Title"), self)
|
||||
self.fileLabel = QLabel(self.tr("Document"), self)
|
||||
self.itemLabel = QLabel(self.tr("Status"), self)
|
||||
self.titleValue = QLabel("", self)
|
||||
self.fileValue = QLabel("", self)
|
||||
self.itemValue = QLabel("", self)
|
||||
|
||||
self.titleLabel.setFont(bFont)
|
||||
self.fileLabel.setFont(bFont)
|
||||
@@ -820,12 +822,12 @@ class GuiOutlineDetails(QScrollArea):
|
||||
self.itemValue.setMaximumWidth(maxTitle)
|
||||
|
||||
# Stats Area
|
||||
self.cCLabel = QLabel(self.tr("Characters"))
|
||||
self.wCLabel = QLabel(self.tr("Words"))
|
||||
self.pCLabel = QLabel(self.tr("Paragraphs"))
|
||||
self.cCValue = QLabel("")
|
||||
self.wCValue = QLabel("")
|
||||
self.pCValue = QLabel("")
|
||||
self.cCLabel = QLabel(self.tr("Characters"), self)
|
||||
self.wCLabel = QLabel(self.tr("Words"), self)
|
||||
self.pCLabel = QLabel(self.tr("Paragraphs"), self)
|
||||
self.cCValue = QLabel("", self)
|
||||
self.wCValue = QLabel("", self)
|
||||
self.pCValue = QLabel("", self)
|
||||
|
||||
self.cCLabel.setFont(bFont)
|
||||
self.wCLabel.setFont(bFont)
|
||||
@@ -839,10 +841,10 @@ class GuiOutlineDetails(QScrollArea):
|
||||
self.pCValue.setAlignment(QtAlignRight)
|
||||
|
||||
# Synopsis
|
||||
self.synopLabel = QLabel(self.tr("Synopsis"))
|
||||
self.synopLabel = QLabel(self.tr("Synopsis"), self)
|
||||
self.synopLabel.setFont(bFont)
|
||||
|
||||
self.synopValue = QLabel("")
|
||||
self.synopValue = QLabel("", self)
|
||||
self.synopValue.setWordWrap(True)
|
||||
self.synopValue.setAlignment(QtAlignLeftTop)
|
||||
|
||||
@@ -850,15 +852,15 @@ class GuiOutlineDetails(QScrollArea):
|
||||
self.synopLWrap.addWidget(self.synopValue, 1)
|
||||
|
||||
# Tags
|
||||
self.povKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]))
|
||||
self.focKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]))
|
||||
self.chrKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]))
|
||||
self.pltKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]))
|
||||
self.timKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]))
|
||||
self.wldKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]))
|
||||
self.objKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]))
|
||||
self.entKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]))
|
||||
self.cstKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]))
|
||||
self.povKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]), self)
|
||||
self.focKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]), self)
|
||||
self.chrKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]), self)
|
||||
self.pltKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]), self)
|
||||
self.timKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]), self)
|
||||
self.wldKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]), self)
|
||||
self.objKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]), self)
|
||||
self.entKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]), self)
|
||||
self.cstKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]), self)
|
||||
|
||||
self.povKeyLabel.setFont(bFont)
|
||||
self.focKeyLabel.setFont(bFont)
|
||||
@@ -880,15 +882,15 @@ class GuiOutlineDetails(QScrollArea):
|
||||
self.entKeyLWrap = QHBoxLayout()
|
||||
self.cstKeyLWrap = QHBoxLayout()
|
||||
|
||||
self.povKeyValue = QLabel("")
|
||||
self.focKeyValue = QLabel("")
|
||||
self.chrKeyValue = QLabel("")
|
||||
self.pltKeyValue = QLabel("")
|
||||
self.timKeyValue = QLabel("")
|
||||
self.wldKeyValue = QLabel("")
|
||||
self.objKeyValue = QLabel("")
|
||||
self.entKeyValue = QLabel("")
|
||||
self.cstKeyValue = QLabel("")
|
||||
self.povKeyValue = QLabel("", self)
|
||||
self.focKeyValue = QLabel("", self)
|
||||
self.chrKeyValue = QLabel("", self)
|
||||
self.pltKeyValue = QLabel("", self)
|
||||
self.timKeyValue = QLabel("", self)
|
||||
self.wldKeyValue = QLabel("", self)
|
||||
self.objKeyValue = QLabel("", self)
|
||||
self.entKeyValue = QLabel("", self)
|
||||
self.cstKeyValue = QLabel("", self)
|
||||
|
||||
self.povKeyValue.setWordWrap(True)
|
||||
self.focKeyValue.setWordWrap(True)
|
||||
@@ -975,7 +977,7 @@ class GuiOutlineDetails(QScrollArea):
|
||||
self.tagsForm.setVerticalSpacing(vSpace)
|
||||
|
||||
# Assemble
|
||||
self.outerWidget = QWidget()
|
||||
self.outerWidget = QWidget(self)
|
||||
self.outerBox = QHBoxLayout()
|
||||
self.outerBox.addWidget(self.mainGroup, 0)
|
||||
self.outerBox.addWidget(self.tagsGroup, 1)
|
||||
|
||||
+11
-11
@@ -32,10 +32,10 @@ from enum import Enum
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import (
|
||||
QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
|
||||
)
|
||||
from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
|
||||
QLabel, QMenu, QShortcut, QSizePolicy, QTreeWidget, QTreeWidgetItem,
|
||||
@@ -54,7 +54,7 @@ from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
||||
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRight
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtUserRole
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -271,7 +271,7 @@ class GuiProjectToolBar(QWidget):
|
||||
self.setAutoFillBackground(True)
|
||||
|
||||
# Widget Label
|
||||
self.viewLabel = QLabel(self.tr("Project Content"))
|
||||
self.viewLabel = QLabel(self.tr("Project Content"), self)
|
||||
self.viewLabel.setFont(SHARED.theme.guiFontB)
|
||||
self.viewLabel.setContentsMargins(0, 0, 0, 0)
|
||||
self.viewLabel.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
@@ -487,8 +487,8 @@ class GuiProjectTree(QTreeWidget):
|
||||
C_ACTIVE = 2
|
||||
C_STATUS = 3
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_WORDS = Qt.ItemDataRole.UserRole + 1
|
||||
D_HANDLE = QtUserRole
|
||||
D_WORDS = QtUserRole + 1
|
||||
|
||||
itemRefreshed = pyqtSignal(str, NWItem, QIcon)
|
||||
|
||||
@@ -1230,7 +1230,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
else:
|
||||
ctxMenu.buildSingleSelectMenu(hasChild)
|
||||
|
||||
ctxMenu.exec_(self.viewport().mapToGlobal(clickPos))
|
||||
ctxMenu.exec(self.viewport().mapToGlobal(clickPos))
|
||||
ctxMenu.deleteLater()
|
||||
|
||||
return True
|
||||
@@ -1256,11 +1256,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
for viewing if the user middle-clicked.
|
||||
"""
|
||||
super().mousePressEvent(event)
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
if event.button() == QtMouseLeft:
|
||||
selItem = self.indexAt(event.pos())
|
||||
if not selItem.isValid():
|
||||
self.clearSelection()
|
||||
elif event.button() == Qt.MouseButton.MiddleButton:
|
||||
elif event.button() == QtMouseMiddle:
|
||||
selItem = self.itemAt(event.pos())
|
||||
if selItem:
|
||||
tHandle = selItem.data(self.C_DATA, self.D_HANDLE)
|
||||
@@ -1268,7 +1268,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
self.projView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, "", False)
|
||||
return
|
||||
|
||||
def startDrag(self, dropAction: Qt.DropActions) -> None:
|
||||
def startDrag(self, dropAction: Qt.DropAction) -> None:
|
||||
"""Capture the drag and drop handling to pop alerts."""
|
||||
super().startDrag(dropAction)
|
||||
if self._popAlert:
|
||||
@@ -1410,7 +1410,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
itemList.remove(tHandle)
|
||||
|
||||
dlgMerge = GuiDocMerge(self.mainGui, tHandle, itemList)
|
||||
dlgMerge.exec_()
|
||||
dlgMerge.exec()
|
||||
|
||||
if dlgMerge.result() == QDialog.DialogCode.Accepted:
|
||||
|
||||
@@ -1480,7 +1480,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
return False
|
||||
|
||||
dlgSplit = GuiDocSplit(self.mainGui, tHandle)
|
||||
dlgSplit.exec_()
|
||||
dlgSplit.exec()
|
||||
|
||||
if dlgSplit.result() == QDialog.DialogCode.Accepted:
|
||||
|
||||
|
||||
@@ -30,15 +30,15 @@ from time import time
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCursor, QKeyEvent
|
||||
from PyQt5.QtWidgets import (
|
||||
QFrame, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QToolBar, QTreeWidget,
|
||||
QTreeWidgetItem, QVBoxLayout, QWidget, qApp
|
||||
QApplication, QFrame, QHBoxLayout, QHeaderView, QLabel, QLineEdit,
|
||||
QToolBar, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import checkInt, cssCol
|
||||
from novelwriter.core.coretools import DocSearch
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.types import QtAlignMiddle, QtAlignRight
|
||||
from novelwriter.types import QtAlignMiddle, QtAlignRight, QtUserRole
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -49,8 +49,8 @@ class GuiProjectSearch(QWidget):
|
||||
C_RESULT = 0
|
||||
C_COUNT = 1
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_RESULT = Qt.ItemDataRole.UserRole + 1
|
||||
D_HANDLE = QtUserRole
|
||||
D_RESULT = QtUserRole + 1
|
||||
|
||||
selectedItemChanged = pyqtSignal(str)
|
||||
openDocumentSelectRequest = pyqtSignal(str, int, int, bool)
|
||||
@@ -71,7 +71,7 @@ class GuiProjectSearch(QWidget):
|
||||
self._map: dict[str, tuple[int, float]] = {}
|
||||
|
||||
# Header
|
||||
self.viewLabel = QLabel(self.tr("Project Search"))
|
||||
self.viewLabel = QLabel(self.tr("Project Search"), self)
|
||||
self.viewLabel.setFont(SHARED.theme.guiFontB)
|
||||
self.viewLabel.setContentsMargins(mPx, tPx, 0, mPx)
|
||||
|
||||
@@ -257,7 +257,7 @@ class GuiProjectSearch(QWidget):
|
||||
def _processSearch(self) -> None:
|
||||
"""Perform a search."""
|
||||
if not self._blocked:
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
start = time()
|
||||
SHARED.mainGui.saveDocument()
|
||||
self._blocked = True
|
||||
@@ -271,7 +271,7 @@ class GuiProjectSearch(QWidget):
|
||||
self._displayResultSet(item, results, capped)
|
||||
logger.debug("Search took %.3f ms", 1000*(time() - start))
|
||||
self._time = time()
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
self._blocked = False
|
||||
return
|
||||
|
||||
@@ -355,7 +355,7 @@ class GuiProjectSearch(QWidget):
|
||||
for i in range(tItem.childCount()):
|
||||
self.searchResult.setFirstColumnSpanned(i, parent, True)
|
||||
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ class GuiSideBar(QWidget):
|
||||
def updateTheme(self) -> None:
|
||||
"""Initialise GUI elements that depend on specific settings."""
|
||||
qPalette = self.palette()
|
||||
qPalette.setBrush(QPalette.Window, qPalette.base())
|
||||
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
||||
self.setPalette(qPalette)
|
||||
|
||||
buttonStyle = SHARED.theme.getStyleSheet(STYLES_BIG_TOOLBUTTON)
|
||||
@@ -157,7 +157,7 @@ class _PopRightMenu(QMenu):
|
||||
|
||||
def event(self, event: QEvent) -> bool:
|
||||
"""Overload the show event and move the menu popup location."""
|
||||
if event.type() == QEvent.Show:
|
||||
if event.type() == QEvent.Type.Show:
|
||||
if isinstance(parent := self.parent(), QWidget):
|
||||
offset = QPoint(parent.width(), parent.height() - self.height())
|
||||
self.move(parent.mapToGlobal(offset))
|
||||
|
||||
@@ -25,12 +25,12 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
from datetime import datetime
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QLocale
|
||||
from PyQt5.QtWidgets import qApp, QStatusBar, QLabel
|
||||
from PyQt5.QtWidgets import QApplication, QStatusBar, QLabel
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import formatTime
|
||||
@@ -66,8 +66,8 @@ class GuiMainStatus(QStatusBar):
|
||||
xM = CONFIG.pxInt(8)
|
||||
|
||||
# The Spell Checker Language
|
||||
self.langIcon = QLabel("")
|
||||
self.langText = QLabel(self.tr("None"))
|
||||
self.langIcon = QLabel("", self)
|
||||
self.langText = QLabel(self.tr("None"), self)
|
||||
self.langIcon.setContentsMargins(0, 0, 0, 0)
|
||||
self.langText.setContentsMargins(0, 0, xM, 0)
|
||||
self.addPermanentWidget(self.langIcon)
|
||||
@@ -75,7 +75,7 @@ class GuiMainStatus(QStatusBar):
|
||||
|
||||
# The Editor Status
|
||||
self.docIcon = StatusLED(colNone, colSaved, colUnsaved, iPx, iPx, self)
|
||||
self.docText = QLabel(self.tr("Editor"))
|
||||
self.docText = QLabel(self.tr("Editor"), self)
|
||||
self.docIcon.setContentsMargins(0, 0, 0, 0)
|
||||
self.docText.setContentsMargins(0, 0, xM, 0)
|
||||
self.addPermanentWidget(self.docIcon)
|
||||
@@ -83,15 +83,15 @@ class GuiMainStatus(QStatusBar):
|
||||
|
||||
# The Project Status
|
||||
self.projIcon = StatusLED(colNone, colSaved, colUnsaved, iPx, iPx, self)
|
||||
self.projText = QLabel(self.tr("Project"))
|
||||
self.projText = QLabel(self.tr("Project"), self)
|
||||
self.projIcon.setContentsMargins(0, 0, 0, 0)
|
||||
self.projText.setContentsMargins(0, 0, xM, 0)
|
||||
self.addPermanentWidget(self.projIcon)
|
||||
self.addPermanentWidget(self.projText)
|
||||
|
||||
# The Project and Session Stats
|
||||
self.statsIcon = QLabel()
|
||||
self.statsText = QLabel("")
|
||||
self.statsIcon = QLabel(self)
|
||||
self.statsText = QLabel("", self)
|
||||
self.statsIcon.setContentsMargins(0, 0, 0, 0)
|
||||
self.statsText.setContentsMargins(0, 0, xM, 0)
|
||||
self.addPermanentWidget(self.statsIcon)
|
||||
@@ -99,8 +99,8 @@ class GuiMainStatus(QStatusBar):
|
||||
|
||||
# The Session Clock
|
||||
# Set the minimum width so the label doesn't rescale every second
|
||||
self.timeIcon = QLabel()
|
||||
self.timeText = QLabel("")
|
||||
self.timeIcon = QLabel(self)
|
||||
self.timeText = QLabel("", self)
|
||||
self.timeText.setToolTip(self.tr("Session Time"))
|
||||
self.timeText.setMinimumWidth(SHARED.theme.getTextWidth("00:00:00:"))
|
||||
self.timeIcon.setContentsMargins(0, 0, 0, 0)
|
||||
@@ -198,7 +198,7 @@ class GuiMainStatus(QStatusBar):
|
||||
def setStatusMessage(self, message: str) -> None:
|
||||
"""Set the status bar message to display."""
|
||||
self.showMessage(message, nwConst.STATUS_MSG_TIMEOUT)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
@@ -240,7 +240,7 @@ class GuiMainStatus(QStatusBar):
|
||||
import tracemalloc
|
||||
from collections import Counter
|
||||
|
||||
widgets = qApp.allWidgets()
|
||||
widgets = QApplication.allWidgets()
|
||||
if not self._debugInfo:
|
||||
if tracemalloc.is_tracing():
|
||||
self._traceMallocRef = "Total"
|
||||
|
||||
+14
-12
@@ -30,16 +30,16 @@ from math import ceil
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtCore import QSize, Qt
|
||||
from PyQt5.QtWidgets import qApp
|
||||
from PyQt5.QtGui import (
|
||||
QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap
|
||||
)
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
|
||||
from novelwriter.error import logException
|
||||
from novelwriter.common import NWConfigParser, cssCol, minmax
|
||||
from novelwriter.constants import nwLabels
|
||||
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
|
||||
from novelwriter.error import logException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -144,15 +144,15 @@ class GuiTheme:
|
||||
self.getHeaderDecorationNarrow = self.iconCache.getHeaderDecorationNarrow
|
||||
|
||||
# Extract Other Info
|
||||
self.guiDPI = qApp.primaryScreen().logicalDotsPerInchX()
|
||||
self.guiScale = qApp.primaryScreen().logicalDotsPerInchX()/96.0
|
||||
self.guiDPI = QApplication.primaryScreen().logicalDotsPerInchX()
|
||||
self.guiScale = QApplication.primaryScreen().logicalDotsPerInchX()/96.0
|
||||
CONFIG.guiScale = self.guiScale
|
||||
logger.debug("GUI DPI: %.1f", self.guiDPI)
|
||||
logger.debug("GUI Scale: %.2f", self.guiScale)
|
||||
|
||||
# Fonts
|
||||
self.guiFont = qApp.font()
|
||||
self.guiFontB = qApp.font()
|
||||
self.guiFont = QApplication.font()
|
||||
self.guiFontB = QApplication.font()
|
||||
self.guiFontB.setBold(True)
|
||||
|
||||
qMetric = QFontMetrics(self.guiFont)
|
||||
@@ -171,7 +171,9 @@ class GuiTheme:
|
||||
# Monospace Font
|
||||
self.guiFontFixed = QFont()
|
||||
self.guiFontFixed.setPointSizeF(0.95*self.fontPointSize)
|
||||
self.guiFontFixed.setFamily(QFontDatabase.systemFont(QFontDatabase.FixedFont).family())
|
||||
self.guiFontFixed.setFamily(
|
||||
QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont).family()
|
||||
)
|
||||
|
||||
logger.debug("GUI Font Family: %s", self.guiFont.family())
|
||||
logger.debug("GUI Font Point Size: %.2f", self.fontPointSize)
|
||||
@@ -255,7 +257,7 @@ class GuiTheme:
|
||||
self._setPalette(parser, sec, "link", QPalette.ColorRole.Link)
|
||||
self._setPalette(parser, sec, "linkvisited", QPalette.ColorRole.LinkVisited)
|
||||
else:
|
||||
self._guiPalette = qApp.style().standardPalette()
|
||||
self._guiPalette = QApplication.style().standardPalette()
|
||||
|
||||
# GUI
|
||||
sec = "GUI"
|
||||
@@ -284,7 +286,7 @@ class GuiTheme:
|
||||
self.iconCache.loadTheme(self.themeIcons or defaultIcons)
|
||||
|
||||
# Apply Styles
|
||||
qApp.setPalette(self._guiPalette)
|
||||
QApplication.setPalette(self._guiPalette)
|
||||
|
||||
# Reset stylesheets so that they are regenerated
|
||||
self._buildStyleSheets(self._guiPalette)
|
||||
@@ -401,14 +403,14 @@ class GuiTheme:
|
||||
font.setFamily("Arial")
|
||||
font.setPointSize(10)
|
||||
else:
|
||||
font = fontDB.systemFont(QFontDatabase.GeneralFont)
|
||||
font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
|
||||
CONFIG.guiFont = font.family()
|
||||
CONFIG.guiFontSize = font.pointSize()
|
||||
else:
|
||||
font.setFamily(CONFIG.guiFont)
|
||||
font.setPointSize(CONFIG.guiFontSize)
|
||||
|
||||
qApp.setFont(font)
|
||||
QApplication.setFont(font)
|
||||
|
||||
return
|
||||
|
||||
|
||||
+30
-29
@@ -30,11 +30,11 @@ from time import time
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor, QIcon
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor, QIcon
|
||||
from PyQt5.QtWidgets import (
|
||||
QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, QSplitter,
|
||||
QStackedWidget, QVBoxLayout, QWidget, qApp
|
||||
QApplication, QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, QSplitter,
|
||||
QStackedWidget, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED, __hexversion__, __version__
|
||||
@@ -109,7 +109,7 @@ class GuiMain(QMainWindow):
|
||||
nwIcon = CONFIG.assetPath("icons") / "novelwriter.svg"
|
||||
self.nwIcon = QIcon(str(nwIcon)) if nwIcon.is_file() else QIcon()
|
||||
self.setWindowIcon(self.nwIcon)
|
||||
qApp.setWindowIcon(self.nwIcon)
|
||||
QApplication.setWindowIcon(self.nwIcon)
|
||||
|
||||
# Build the GUI
|
||||
# =============
|
||||
@@ -148,7 +148,7 @@ class GuiMain(QMainWindow):
|
||||
self.treePane.setLayout(self.treeBox)
|
||||
|
||||
# Splitter : Document Viewer / Document Meta
|
||||
self.splitView = QSplitter(Qt.Vertical, self)
|
||||
self.splitView = QSplitter(Qt.Orientation.Vertical, self)
|
||||
self.splitView.addWidget(self.docViewer)
|
||||
self.splitView.addWidget(self.docViewerPanel)
|
||||
self.splitView.setHandleWidth(hWd)
|
||||
@@ -158,7 +158,7 @@ class GuiMain(QMainWindow):
|
||||
self.splitView.setCollapsible(1, False)
|
||||
|
||||
# Splitter : Document Editor / Document Viewer
|
||||
self.splitDocs = QSplitter(Qt.Horizontal, self)
|
||||
self.splitDocs = QSplitter(Qt.Orientation.Horizontal, self)
|
||||
self.splitDocs.addWidget(self.docEditor)
|
||||
self.splitDocs.addWidget(self.splitView)
|
||||
self.splitDocs.setOpaqueResize(False)
|
||||
@@ -167,7 +167,7 @@ class GuiMain(QMainWindow):
|
||||
self.splitDocs.setCollapsible(1, False)
|
||||
|
||||
# Splitter : Project Tree / Document Area
|
||||
self.splitMain = QSplitter(Qt.Horizontal)
|
||||
self.splitMain = QSplitter(Qt.Orientation.Horizontal)
|
||||
self.splitMain.setContentsMargins(0, 0, 0, 0)
|
||||
self.splitMain.addWidget(self.treePane)
|
||||
self.splitMain.addWidget(self.splitDocs)
|
||||
@@ -205,7 +205,7 @@ class GuiMain(QMainWindow):
|
||||
self.setMenuBar(self.mainMenu)
|
||||
self.setCentralWidget(self.mainWidget)
|
||||
self.setStatusBar(self.mainStatus)
|
||||
self.setContextMenuPolicy(Qt.NoContextMenu) # Issue #1147
|
||||
self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) # Issue #1147
|
||||
|
||||
# Connect Signals
|
||||
# ===============
|
||||
@@ -328,7 +328,7 @@ class GuiMain(QMainWindow):
|
||||
def postLaunchTasks(self, cmdOpen: str | None) -> None:
|
||||
"""Process tasks after the main window has been created."""
|
||||
if cmdOpen:
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
logger.info("Command line path: %s", cmdOpen)
|
||||
self.openProject(cmdOpen)
|
||||
|
||||
@@ -474,12 +474,12 @@ class GuiMain(QMainWindow):
|
||||
break
|
||||
|
||||
if lastEdited is not None:
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.openDocument(lastEdited, doScroll=True)
|
||||
|
||||
lastViewed = SHARED.project.data.getLastHandle("viewer")
|
||||
if lastViewed is not None:
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.viewDocument(lastViewed)
|
||||
|
||||
# Check if we need to rebuild the index
|
||||
@@ -488,7 +488,7 @@ class GuiMain(QMainWindow):
|
||||
self.rebuildIndex()
|
||||
|
||||
# Make sure the changed status is set to false on things opened
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.docEditor.setDocumentChanged(False)
|
||||
SHARED.project.setProjectChanged(False)
|
||||
|
||||
@@ -738,7 +738,7 @@ class GuiMain(QMainWindow):
|
||||
"""Rebuild the entire index."""
|
||||
if SHARED.hasProject:
|
||||
logger.info("Rebuilding index ...")
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
tStart = time()
|
||||
|
||||
self.projView.saveProjectTasks()
|
||||
@@ -752,7 +752,7 @@ class GuiMain(QMainWindow):
|
||||
)
|
||||
self.docEditor.updateTagHighLighting()
|
||||
self._updateStatusWordCount()
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
if not beQuiet:
|
||||
SHARED.info(self.tr("The project index has been successfully rebuilt."))
|
||||
@@ -768,7 +768,7 @@ class GuiMain(QMainWindow):
|
||||
"""Open the welcome dialog."""
|
||||
dialog = GuiWelcome(self)
|
||||
dialog.openProjectRequest.connect(self._openProjectFromWelcome)
|
||||
dialog.exec_()
|
||||
dialog.exec()
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -776,7 +776,7 @@ class GuiMain(QMainWindow):
|
||||
"""Open the preferences dialog."""
|
||||
dialog = GuiPreferences(self)
|
||||
dialog.newPreferencesReady.connect(self._processConfigChanges)
|
||||
dialog.exec_()
|
||||
dialog.exec()
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -786,7 +786,7 @@ class GuiMain(QMainWindow):
|
||||
if SHARED.hasProject:
|
||||
dialog = GuiProjectSettings(self, gotoPage=focusTab)
|
||||
dialog.newProjectSettingsReady.connect(self._processProjectSettingsChanges)
|
||||
dialog.exec_()
|
||||
dialog.exec()
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -797,7 +797,7 @@ class GuiMain(QMainWindow):
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
dialog.updateValues()
|
||||
return
|
||||
|
||||
@@ -810,7 +810,7 @@ class GuiMain(QMainWindow):
|
||||
dialog.setModal(False)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
dialog.loadContent()
|
||||
return
|
||||
|
||||
@@ -820,7 +820,7 @@ class GuiMain(QMainWindow):
|
||||
if SHARED.hasProject:
|
||||
dialog = GuiWordList(self)
|
||||
dialog.newWordListReady.connect(self._processWordListChanges)
|
||||
dialog.exec_()
|
||||
dialog.exec()
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -832,7 +832,7 @@ class GuiMain(QMainWindow):
|
||||
dialog.setModal(False)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
dialog.populateGUI()
|
||||
return
|
||||
|
||||
@@ -843,7 +843,7 @@ class GuiMain(QMainWindow):
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
dialog.populateGUI()
|
||||
return
|
||||
|
||||
@@ -861,7 +861,7 @@ class GuiMain(QMainWindow):
|
||||
dialog.setModal(True)
|
||||
dialog.show()
|
||||
dialog.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
if not dialog.initDialog():
|
||||
dialog.close()
|
||||
SHARED.error(self.tr("Could not initialise the dialog."))
|
||||
@@ -899,7 +899,8 @@ class GuiMain(QMainWindow):
|
||||
CONFIG.setViewPanePos(self.splitView.sizes())
|
||||
|
||||
CONFIG.showViewerPanel = self.docViewerPanel.isVisible()
|
||||
if self.windowState() & Qt.WindowFullScreen != Qt.WindowFullScreen:
|
||||
wFull = Qt.WindowState.WindowFullScreen
|
||||
if self.windowState() & wFull != wFull:
|
||||
# Ignore window size if in full screen mode
|
||||
CONFIG.setMainWinSize(self.width(), self.height())
|
||||
|
||||
@@ -909,7 +910,7 @@ class GuiMain(QMainWindow):
|
||||
CONFIG.saveConfig()
|
||||
self.reportConfErr()
|
||||
|
||||
qApp.quit()
|
||||
QApplication.quit()
|
||||
|
||||
return True
|
||||
|
||||
@@ -936,7 +937,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
def toggleFullScreenMode(self) -> None:
|
||||
"""Toggle full screen mode"""
|
||||
self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
|
||||
self.setWindowState(self.windowState() ^ Qt.WindowState.WindowFullScreen)
|
||||
return
|
||||
|
||||
##
|
||||
@@ -1056,7 +1057,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
if theme:
|
||||
# We are doing this manually instead of connecting to
|
||||
# qApp.paletteChanged since the processing order matters
|
||||
# paletteChanged since the processing order matters
|
||||
SHARED.theme.loadTheme()
|
||||
self.docEditor.updateTheme()
|
||||
self.docViewer.updateTheme()
|
||||
@@ -1115,7 +1116,7 @@ class GuiMain(QMainWindow):
|
||||
@pyqtSlot(Path)
|
||||
def _openProjectFromWelcome(self, path: Path) -> None:
|
||||
"""Handle an open project request from the welcome dialog."""
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.openProject(path)
|
||||
if not SHARED.hasProject:
|
||||
self.showWelcomeDialog()
|
||||
@@ -1212,7 +1213,7 @@ class GuiMain(QMainWindow):
|
||||
if SHARED.hasProject:
|
||||
currTime = time()
|
||||
editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime
|
||||
userIdle = qApp.applicationState() != Qt.ApplicationActive
|
||||
userIdle = QApplication.applicationState() != Qt.ApplicationState.ApplicationActive
|
||||
self.mainStatus.setUserIdle(editIdle or userIdle)
|
||||
SHARED.updateIdleTime(currTime, editIdle or userIdle)
|
||||
self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime)
|
||||
|
||||
@@ -292,7 +292,7 @@ class SharedData(QObject):
|
||||
self._lastAlert = alert.logMessage
|
||||
if log:
|
||||
logger.info(self._lastAlert, stacklevel=2)
|
||||
alert.exec_()
|
||||
alert.exec()
|
||||
alert.deleteLater()
|
||||
return
|
||||
|
||||
@@ -304,7 +304,7 @@ class SharedData(QObject):
|
||||
self._lastAlert = alert.logMessage
|
||||
if log:
|
||||
logger.warning(self._lastAlert, stacklevel=2)
|
||||
alert.exec_()
|
||||
alert.exec()
|
||||
alert.deleteLater()
|
||||
return
|
||||
|
||||
@@ -319,7 +319,7 @@ class SharedData(QObject):
|
||||
self._lastAlert = alert.logMessage
|
||||
if log:
|
||||
logger.error(self._lastAlert, stacklevel=2)
|
||||
alert.exec_()
|
||||
alert.exec()
|
||||
alert.deleteLater()
|
||||
return
|
||||
|
||||
@@ -329,7 +329,7 @@ class SharedData(QObject):
|
||||
alert.setMessage(text, info, details)
|
||||
alert.setAlertType(_GuiAlert.WARN if warn else _GuiAlert.ASK, True)
|
||||
self._lastAlert = alert.logMessage
|
||||
alert.exec_()
|
||||
alert.exec()
|
||||
isYes = alert.result() == QMessageBox.StandardButton.Yes
|
||||
alert.deleteLater()
|
||||
return isYes
|
||||
|
||||
@@ -28,17 +28,18 @@ import logging
|
||||
from pathlib import Path
|
||||
from zipfile import ZipFile
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QTextCursor
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QTextCursor
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout, QLabel,
|
||||
QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget, qApp
|
||||
QApplication, QDialog, 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.error import formatException
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.types import QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -70,7 +71,7 @@ class GuiDictionaries(QDialog):
|
||||
self.tr("Download a dictionary from one of the links, and add it below."),
|
||||
f" \u203a <a href='{foUrl}'>{foUrl}</a>",
|
||||
f" \u203a <a href='{loUrl}'>{loUrl}</a>",
|
||||
]))
|
||||
]), self)
|
||||
self.huInfo.setOpenExternalLinks(True)
|
||||
self.huInfo.setWordWrap(True)
|
||||
self.huInput = QLineEdit(self)
|
||||
@@ -89,7 +90,7 @@ class GuiDictionaries(QDialog):
|
||||
self.huAddBox.addWidget(self.huImport)
|
||||
|
||||
# Install Path
|
||||
self.inInfo = QLabel(self.tr("Dictionary install location"))
|
||||
self.inInfo = QLabel(self.tr("Dictionary install location"), self)
|
||||
self.inPath = QLineEdit(self)
|
||||
self.inPath.setReadOnly(True)
|
||||
self.inBrowse = NIconToolButton(self, iSz, "browse")
|
||||
@@ -107,7 +108,7 @@ class GuiDictionaries(QDialog):
|
||||
self.infoBox.setFrameStyle(QFrame.Shape.NoFrame)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogClose, self)
|
||||
self.buttonBox.rejected.connect(self._doClose)
|
||||
|
||||
# Assemble
|
||||
@@ -158,7 +159,7 @@ class GuiDictionaries(QDialog):
|
||||
"Additional dictionaries found: {0}"
|
||||
).format(len(self._currDicts)))
|
||||
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
self.adjustSize()
|
||||
|
||||
return True
|
||||
|
||||
+11
-10
@@ -35,7 +35,7 @@ from PyQt5.QtWidgets import (
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import readTextFile
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRight
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRight, QtRoleAction, QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -61,7 +61,7 @@ class GuiLipsum(QDialog):
|
||||
self.innerBox.setSpacing(CONFIG.pxInt(16))
|
||||
|
||||
# Icon
|
||||
self.docIcon = QLabel()
|
||||
self.docIcon = QLabel(self)
|
||||
self.docIcon.setPixmap(SHARED.theme.getPixmap("proj_document", (nPx, nPx)))
|
||||
|
||||
self.leftBox = QVBoxLayout()
|
||||
@@ -71,15 +71,16 @@ class GuiLipsum(QDialog):
|
||||
self.innerBox.addLayout(self.leftBox)
|
||||
|
||||
# Form
|
||||
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Insert Lorem Ipsum Text")))
|
||||
self.headLabel = QLabel(self.tr("Insert Lorem Ipsum Text"))
|
||||
self.headLabel.setFont(SHARED.theme.guiFontB)
|
||||
|
||||
self.paraLabel = QLabel(self.tr("Number of paragraphs"))
|
||||
self.paraCount = QSpinBox()
|
||||
self.paraLabel = QLabel(self.tr("Number of paragraphs"), self)
|
||||
self.paraCount = QSpinBox(self)
|
||||
self.paraCount.setMinimum(1)
|
||||
self.paraCount.setMaximum(100)
|
||||
self.paraCount.setValue(5)
|
||||
|
||||
self.randLabel = QLabel(self.tr("Randomise order"))
|
||||
self.randLabel = QLabel(self.tr("Randomise order"), self)
|
||||
self.randSwitch = NSwitch(self)
|
||||
|
||||
self.formBox = QGridLayout()
|
||||
@@ -93,13 +94,13 @@ class GuiLipsum(QDialog):
|
||||
self.innerBox.addLayout(self.formBox)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox()
|
||||
self.buttonBox = QDialogButtonBox(self)
|
||||
self.buttonBox.rejected.connect(self.close)
|
||||
|
||||
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
|
||||
self.btnClose = self.buttonBox.addButton(QtDialogClose)
|
||||
self.btnClose.setAutoDefault(False)
|
||||
|
||||
self.btnInsert = self.buttonBox.addButton(self.tr("Insert"), QDialogButtonBox.ActionRole)
|
||||
self.btnInsert = self.buttonBox.addButton(self.tr("Insert"), QtRoleAction)
|
||||
self.btnInsert.clicked.connect(self._doInsert)
|
||||
self.btnInsert.setAutoDefault(False)
|
||||
|
||||
@@ -129,7 +130,7 @@ class GuiLipsum(QDialog):
|
||||
def getLipsum(cls, parent: QWidget) -> str:
|
||||
"""Pop the dialog and return the lipsum text."""
|
||||
cls = GuiLipsum(parent)
|
||||
cls.exec_()
|
||||
cls.exec()
|
||||
text = cls.lipsumText
|
||||
cls.deleteLater()
|
||||
return text
|
||||
|
||||
@@ -27,8 +27,8 @@ import logging
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtCore import QTimer, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtCore import QTimer, Qt, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog,
|
||||
QGridLayout, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem,
|
||||
@@ -44,7 +44,9 @@ from novelwriter.core.item import NWItem
|
||||
from novelwriter.enum import nwBuildFmt
|
||||
from novelwriter.extensions.modified import NIconToolButton
|
||||
from novelwriter.extensions.simpleprogress import NProgressSimple
|
||||
from novelwriter.types import QtAlignCenter
|
||||
from novelwriter.types import (
|
||||
QtAlignCenter, QtDialogClose, QtRoleAction, QtRoleReject, QtUserRole
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -56,7 +58,7 @@ class GuiManuscriptBuild(QDialog):
|
||||
independently of the Manuscript Build Tool.
|
||||
"""
|
||||
|
||||
D_KEY = Qt.ItemDataRole.UserRole
|
||||
D_KEY = QtUserRole
|
||||
|
||||
def __init__(self, parent: QWidget, build: BuildSettings):
|
||||
super().__init__(parent=parent)
|
||||
@@ -88,8 +90,8 @@ class GuiManuscriptBuild(QDialog):
|
||||
# Output Format
|
||||
# =============
|
||||
|
||||
self.lblFormat = QLabel(self.tr("Output Format"))
|
||||
self.listFormats = QListWidget()
|
||||
self.lblFormat = QLabel(self.tr("Output Format"), self)
|
||||
self.listFormats = QListWidget(self)
|
||||
self.listFormats.setIconSize(iSz)
|
||||
current = None
|
||||
for key in nwBuildFmt:
|
||||
@@ -107,14 +109,14 @@ class GuiManuscriptBuild(QDialog):
|
||||
self.formatBox.addWidget(self.listFormats, 1)
|
||||
self.formatBox.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.formatWidget = QWidget()
|
||||
self.formatWidget = QWidget(self)
|
||||
self.formatWidget.setLayout(self.formatBox)
|
||||
self.formatWidget.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# Table of Contents
|
||||
# =================
|
||||
|
||||
self.lblContent = QLabel(self.tr("Table of Contents"))
|
||||
self.lblContent = QLabel(self.tr("Table of Contents"), self)
|
||||
|
||||
self.listContent = QListWidget(self)
|
||||
self.listContent.setIconSize(iSz)
|
||||
@@ -125,7 +127,7 @@ class GuiManuscriptBuild(QDialog):
|
||||
self.contentBox.addWidget(self.listContent, 0)
|
||||
self.contentBox.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.contentWidget = QWidget()
|
||||
self.contentWidget = QWidget(self)
|
||||
self.contentWidget.setLayout(self.contentBox)
|
||||
self.contentWidget.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
@@ -137,12 +139,12 @@ class GuiManuscriptBuild(QDialog):
|
||||
font.setUnderline(True)
|
||||
font.setPointSizeF(1.5*font.pointSizeF())
|
||||
|
||||
self.lblMain = QLabel(self._build.name)
|
||||
self.lblMain = QLabel(self._build.name, self)
|
||||
self.lblMain.setWordWrap(True)
|
||||
self.lblMain.setFont(font)
|
||||
|
||||
# Build Path
|
||||
self.lblPath = QLabel(self.tr("Path"))
|
||||
self.lblPath = QLabel(self.tr("Path"), self)
|
||||
self.buildPath = QLineEdit(self)
|
||||
self.btnBrowse = NIconToolButton(self, iSz, "browse")
|
||||
|
||||
@@ -152,7 +154,7 @@ class GuiManuscriptBuild(QDialog):
|
||||
self.pathBox.setSpacing(sp8)
|
||||
|
||||
# Build Name
|
||||
self.lblName = QLabel(self.tr("File Name"))
|
||||
self.lblName = QLabel(self.tr("File Name"), self)
|
||||
self.buildName = QLineEdit(self)
|
||||
self.btnReset = NIconToolButton(self, iSz, "revert")
|
||||
self.btnReset.setToolTip(self.tr("Reset file name to default"))
|
||||
@@ -179,19 +181,19 @@ class GuiManuscriptBuild(QDialog):
|
||||
self.buildBox.setVerticalSpacing(sp4)
|
||||
|
||||
# Dialog Buttons
|
||||
self.btnOpen = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Open Folder"))
|
||||
self.btnOpen = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Open Folder"), self)
|
||||
self.btnOpen.setIconSize(bSz)
|
||||
self.btnBuild = QPushButton(SHARED.theme.getIcon("export"), self.tr("&Build"))
|
||||
self.btnBuild = QPushButton(SHARED.theme.getIcon("export"), self.tr("&Build"), self)
|
||||
self.btnBuild.setIconSize(bSz)
|
||||
|
||||
self.dlgButtons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
|
||||
self.dlgButtons.addButton(self.btnOpen, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.dlgButtons.addButton(self.btnBuild, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.dlgButtons = QDialogButtonBox(QtDialogClose, self)
|
||||
self.dlgButtons.addButton(self.btnOpen, QtRoleAction)
|
||||
self.dlgButtons.addButton(self.btnBuild, QtRoleAction)
|
||||
|
||||
# Assemble GUI
|
||||
# ============
|
||||
|
||||
self.mainSplit = QSplitter()
|
||||
self.mainSplit = QSplitter(self)
|
||||
self.mainSplit.addWidget(self.formatWidget)
|
||||
self.mainSplit.addWidget(self.contentWidget)
|
||||
self.mainSplit.setHandleWidth(sp16)
|
||||
@@ -261,12 +263,12 @@ class GuiManuscriptBuild(QDialog):
|
||||
def _dialogButtonClicked(self, button: QAbstractButton):
|
||||
"""Handle button clicks from the dialog button box."""
|
||||
role = self.dlgButtons.buttonRole(button)
|
||||
if role == QDialogButtonBox.ActionRole:
|
||||
if role == QtRoleAction:
|
||||
if button == self.btnBuild:
|
||||
self._runBuild()
|
||||
elif button == self.btnOpen:
|
||||
self._openOutputFolder()
|
||||
elif role == QDialogButtonBox.RejectRole:
|
||||
elif role == QtRoleReject:
|
||||
self.close()
|
||||
return
|
||||
|
||||
|
||||
@@ -26,19 +26,19 @@ from __future__ import annotations
|
||||
import json
|
||||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
from datetime import datetime
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
|
||||
from PyQt5.QtCore import QTimer, QUrl, Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QDialog, QFormLayout, QGridLayout, QHBoxLayout, QLabel,
|
||||
QListWidget, QListWidgetItem, QPushButton, QSizePolicy, QSplitter,
|
||||
QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget, qApp
|
||||
)
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
|
||||
from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
|
||||
QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton,
|
||||
QSizePolicy, QSplitter, QStackedWidget, QTabWidget, QTextBrowser,
|
||||
QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import checkInt, fuzzyTime
|
||||
@@ -53,7 +53,8 @@ from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
|
||||
from novelwriter.tools.manusbuild import GuiManuscriptBuild
|
||||
from novelwriter.tools.manussettings import GuiBuildSettings
|
||||
from novelwriter.types import (
|
||||
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignRight, QtAlignTop
|
||||
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignRight, QtAlignTop,
|
||||
QtUserRole
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
@@ -70,7 +71,7 @@ class GuiManuscript(QDialog):
|
||||
a document directly to disk.
|
||||
"""
|
||||
|
||||
D_KEY = Qt.ItemDataRole.UserRole
|
||||
D_KEY = QtUserRole
|
||||
|
||||
def __init__(self, mainGui: GuiMain) -> None:
|
||||
super().__init__(parent=mainGui)
|
||||
@@ -103,7 +104,7 @@ class GuiManuscript(QDialog):
|
||||
# ==============
|
||||
|
||||
qPalette = self.palette()
|
||||
qPalette.setBrush(QPalette.Window, qPalette.base())
|
||||
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
||||
self.setPalette(qPalette)
|
||||
|
||||
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
||||
@@ -123,7 +124,7 @@ class GuiManuscript(QDialog):
|
||||
self.tbEdit.setStyleSheet(buttonStyle)
|
||||
self.tbEdit.clicked.connect(self._editSelectedBuild)
|
||||
|
||||
self.lblBuilds = QLabel("<b>{0}</b>".format(self.tr("Builds")))
|
||||
self.lblBuilds = QLabel("<b>{0}</b>".format(self.tr("Builds")), self)
|
||||
|
||||
self.listToolBox = QHBoxLayout()
|
||||
self.listToolBox.addWidget(self.lblBuilds)
|
||||
@@ -140,8 +141,8 @@ class GuiManuscript(QDialog):
|
||||
self.buildList.setIconSize(iSz)
|
||||
self.buildList.doubleClicked.connect(self._editSelectedBuild)
|
||||
self.buildList.currentItemChanged.connect(self._updateBuildDetails)
|
||||
self.buildList.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
self.buildList.setDragDropMode(QAbstractItemView.InternalMove)
|
||||
self.buildList.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
|
||||
self.buildList.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
||||
|
||||
# Details Tabs
|
||||
# ============
|
||||
@@ -169,16 +170,16 @@ class GuiManuscript(QDialog):
|
||||
# Process Controls
|
||||
# ================
|
||||
|
||||
self.btnPreview = QPushButton(self.tr("Preview"))
|
||||
self.btnPreview = QPushButton(self.tr("Preview"), self)
|
||||
self.btnPreview.clicked.connect(self._generatePreview)
|
||||
|
||||
self.btnPrint = QPushButton(self.tr("Print"))
|
||||
self.btnPrint = QPushButton(self.tr("Print"), self)
|
||||
self.btnPrint.clicked.connect(self._printDocument)
|
||||
|
||||
self.btnBuild = QPushButton(self.tr("Build"))
|
||||
self.btnBuild = QPushButton(self.tr("Build"), self)
|
||||
self.btnBuild.clicked.connect(self._buildManuscript)
|
||||
|
||||
self.btnClose = QPushButton(self.tr("Close"))
|
||||
self.btnClose = QPushButton(self.tr("Close"), self)
|
||||
self.btnClose.clicked.connect(self.close)
|
||||
|
||||
self.processBox = QGridLayout()
|
||||
@@ -210,7 +211,7 @@ class GuiManuscript(QDialog):
|
||||
self.optsWidget = QWidget(self)
|
||||
self.optsWidget.setLayout(self.controlBox)
|
||||
|
||||
self.mainSplit = QSplitter()
|
||||
self.mainSplit = QSplitter(self)
|
||||
self.mainSplit.addWidget(self.optsWidget)
|
||||
self.mainSplit.addWidget(self.docWdiget)
|
||||
self.mainSplit.setCollapsible(0, False)
|
||||
@@ -352,7 +353,7 @@ class GuiManuscript(QDialog):
|
||||
self.docPreview.beginNewBuild(len(docBuild))
|
||||
for step, _ in docBuild.iterBuildHTML(None):
|
||||
self.docPreview.buildStep(step + 1)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
|
||||
buildObj = docBuild.lastBuild
|
||||
assert isinstance(buildObj, ToHtml)
|
||||
@@ -385,7 +386,7 @@ class GuiManuscript(QDialog):
|
||||
build = self._getSelectedBuild()
|
||||
if isinstance(build, BuildSettings):
|
||||
dlgBuild = GuiManuscriptBuild(self, build)
|
||||
dlgBuild.exec_()
|
||||
dlgBuild.exec()
|
||||
|
||||
# After the build is done, save build settings changes
|
||||
if build.changed:
|
||||
@@ -398,7 +399,7 @@ class GuiManuscript(QDialog):
|
||||
"""Open the print preview dialog."""
|
||||
preview = QPrintPreviewDialog(self)
|
||||
preview.paintRequested.connect(self.docPreview.printPreview)
|
||||
preview.exec_()
|
||||
preview.exec()
|
||||
return
|
||||
|
||||
##
|
||||
@@ -486,7 +487,7 @@ class GuiManuscript(QDialog):
|
||||
dlgSettings.setModal(False)
|
||||
dlgSettings.show()
|
||||
dlgSettings.raise_()
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
dlgSettings.loadContent()
|
||||
dlgSettings.newSettingsReady.connect(self._processNewSettings)
|
||||
|
||||
@@ -661,7 +662,7 @@ class _DetailsWidget(QWidget):
|
||||
|
||||
class _OutlineWidget(QWidget):
|
||||
|
||||
D_LINE = Qt.ItemDataRole.UserRole
|
||||
D_LINE = QtUserRole
|
||||
|
||||
outlineEntryClicked = pyqtSignal(str)
|
||||
|
||||
@@ -750,8 +751,8 @@ class _PreviewWidget(QTextBrowser):
|
||||
|
||||
# Document Setup
|
||||
dPalette = self.palette()
|
||||
dPalette.setColor(QPalette.Base, QColor(255, 255, 255))
|
||||
dPalette.setColor(QPalette.Text, QColor(0, 0, 0))
|
||||
dPalette.setColor(QPalette.ColorRole.Base, QColor(255, 255, 255))
|
||||
dPalette.setColor(QPalette.ColorRole.Text, QColor(0, 0, 0))
|
||||
self.setPalette(dPalette)
|
||||
|
||||
self.setMinimumWidth(40*SHARED.theme.textNWidth)
|
||||
@@ -768,8 +769,8 @@ class _PreviewWidget(QTextBrowser):
|
||||
|
||||
# Document Age
|
||||
aPalette = self.palette()
|
||||
aPalette.setColor(QPalette.Background, aPalette.toolTipBase().color())
|
||||
aPalette.setColor(QPalette.Foreground, aPalette.toolTipText().color())
|
||||
aPalette.setColor(QPalette.ColorRole.Window, aPalette.toolTipBase().color())
|
||||
aPalette.setColor(QPalette.ColorRole.WindowText, aPalette.toolTipText().color())
|
||||
|
||||
aFont = self.font()
|
||||
aFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
|
||||
@@ -850,16 +851,16 @@ class _PreviewWidget(QTextBrowser):
|
||||
def buildStep(self, value: int) -> None:
|
||||
"""Update the progress bar value."""
|
||||
self.buildProgress.setValue(value)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
def setContent(self, data: dict) -> None:
|
||||
"""Set the content of the preview widget."""
|
||||
sPos = self.verticalScrollBar().value()
|
||||
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
|
||||
self.buildProgress.setCentreText(self.tr("Processing ..."))
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
|
||||
styles = "\n".join(data.get("styles", []))
|
||||
self.document().setDefaultStyleSheet(styles)
|
||||
@@ -867,7 +868,7 @@ class _PreviewWidget(QTextBrowser):
|
||||
html = "".join(data.get("html", []))
|
||||
html = html.replace("\t", "!!tab!!")
|
||||
self.setHtml(html)
|
||||
qApp.processEvents()
|
||||
QApplication.processEvents()
|
||||
while self.find("!!tab!!"):
|
||||
cursor = self.textCursor()
|
||||
cursor.insertText("\t")
|
||||
@@ -881,8 +882,8 @@ class _PreviewWidget(QTextBrowser):
|
||||
self.document().markContentsDirty(0, self.document().characterCount())
|
||||
|
||||
self.buildProgress.setCentreText(self.tr("Done"))
|
||||
qApp.restoreOverrideCursor()
|
||||
qApp.processEvents()
|
||||
QApplication.restoreOverrideCursor()
|
||||
QApplication.processEvents()
|
||||
QTimer.singleShot(300, self._hideProgress)
|
||||
|
||||
return
|
||||
@@ -904,10 +905,10 @@ class _PreviewWidget(QTextBrowser):
|
||||
@pyqtSlot("QPrinter*")
|
||||
def printPreview(self, printer: QPrinter) -> None:
|
||||
"""Connect the print preview painter to the document viewer."""
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
printer.setOrientation(QPrinter.Portrait)
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
printer.setOrientation(QPrinter.Orientation.Portrait)
|
||||
self.document().print(printer)
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
return
|
||||
|
||||
@pyqtSlot(str)
|
||||
@@ -1053,10 +1054,10 @@ class _StatsWidget(QWidget):
|
||||
"""Build the minimal stats page."""
|
||||
mPx = CONFIG.pxInt(8)
|
||||
|
||||
self.lblWordCount = QLabel(self.tr("Words"))
|
||||
self.lblWordCount = QLabel(self.tr("Words"), self)
|
||||
self.minWordCount = QLabel(self)
|
||||
|
||||
self.lblCharCount = QLabel(self.tr("Characters"))
|
||||
self.lblCharCount = QLabel(self.tr("Characters"), self)
|
||||
self.minCharCount = QLabel(self)
|
||||
|
||||
# Assemble
|
||||
|
||||
@@ -46,7 +46,10 @@ from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconTool
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.extensions.switchbox import NSwitchBox
|
||||
from novelwriter.types import QtAlignLeft
|
||||
from novelwriter.types import (
|
||||
QtAlignLeft, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept,
|
||||
QtRoleApply, QtRoleReject, QtUserRole
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -99,7 +102,7 @@ class GuiBuildSettings(QDialog):
|
||||
)
|
||||
|
||||
# Settings Name
|
||||
self.lblBuildName = QLabel(self.tr("Name"))
|
||||
self.lblBuildName = QLabel(self.tr("Name"), self)
|
||||
self.editBuildName = QLineEdit(self)
|
||||
|
||||
# SideBar
|
||||
@@ -131,11 +134,7 @@ class GuiBuildSettings(QDialog):
|
||||
self.toolStack.addWidget(self.optTabOutput)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(
|
||||
QDialogButtonBox.StandardButton.Apply
|
||||
| QDialogButtonBox.StandardButton.Save
|
||||
| QDialogButtonBox.StandardButton.Close
|
||||
)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogApply | QtDialogSave | QtDialogClose, self)
|
||||
self.buttonBox.clicked.connect(self._dialogButtonClicked)
|
||||
|
||||
# Assemble
|
||||
@@ -226,12 +225,12 @@ class GuiBuildSettings(QDialog):
|
||||
def _dialogButtonClicked(self, button: QAbstractButton) -> None:
|
||||
"""Handle button clicks from the dialog button box."""
|
||||
role = self.buttonBox.buttonRole(button)
|
||||
if role == QDialogButtonBox.ApplyRole:
|
||||
if role == QtRoleApply:
|
||||
self._emitBuildData()
|
||||
elif role == QDialogButtonBox.AcceptRole:
|
||||
elif role == QtRoleAccept:
|
||||
self._emitBuildData()
|
||||
self.close()
|
||||
elif role == QDialogButtonBox.RejectRole:
|
||||
elif role == QtRoleReject:
|
||||
self.close()
|
||||
return
|
||||
|
||||
@@ -289,8 +288,8 @@ class _FilterTab(NFixedPage):
|
||||
C_ACTIVE = 1
|
||||
C_STATUS = 2
|
||||
|
||||
D_HANDLE = Qt.ItemDataRole.UserRole
|
||||
D_FILE = Qt.ItemDataRole.UserRole + 1
|
||||
D_HANDLE = QtUserRole
|
||||
D_FILE = QtUserRole + 1
|
||||
|
||||
F_NONE = 0
|
||||
F_FILTERED = 1
|
||||
@@ -332,15 +331,15 @@ class _FilterTab(NFixedPage):
|
||||
treeHeader = self.optTree.header()
|
||||
treeHeader.setStretchLastSection(False)
|
||||
treeHeader.setMinimumSectionSize(iPx + cMg) # See Issue #1551
|
||||
treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.Stretch)
|
||||
treeHeader.setSectionResizeMode(self.C_ACTIVE, QHeaderView.Fixed)
|
||||
treeHeader.setSectionResizeMode(self.C_STATUS, QHeaderView.Fixed)
|
||||
treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.ResizeMode.Stretch)
|
||||
treeHeader.setSectionResizeMode(self.C_ACTIVE, QHeaderView.ResizeMode.Fixed)
|
||||
treeHeader.setSectionResizeMode(self.C_STATUS, QHeaderView.ResizeMode.Fixed)
|
||||
treeHeader.resizeSection(self.C_ACTIVE, iPx + cMg)
|
||||
treeHeader.resizeSection(self.C_STATUS, iPx + cMg)
|
||||
|
||||
self.optTree.setDragDropMode(QAbstractItemView.NoDragDrop)
|
||||
self.optTree.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.optTree.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.optTree.setDragDropMode(QAbstractItemView.DragDropMode.NoDragDrop)
|
||||
self.optTree.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||
self.optTree.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||
|
||||
# Filters
|
||||
# =======
|
||||
@@ -360,7 +359,7 @@ class _FilterTab(NFixedPage):
|
||||
self.resetButton.clicked.connect(lambda: self._setSelectedMode(self.F_FILTERED))
|
||||
|
||||
self.modeBox = QHBoxLayout()
|
||||
self.modeBox.addWidget(QLabel(self.tr("Mark selection as")))
|
||||
self.modeBox.addWidget(QLabel(self.tr("Mark selection as"), self))
|
||||
self.modeBox.addStretch(1)
|
||||
self.modeBox.addWidget(self.includedButton)
|
||||
self.modeBox.addWidget(self.excludedButton)
|
||||
@@ -370,7 +369,7 @@ class _FilterTab(NFixedPage):
|
||||
# Filer Options
|
||||
self.filterOpt = NSwitchBox(self, iPx)
|
||||
self.filterOpt.switchToggled.connect(self._applyFilterSwitch)
|
||||
self.filterOpt.setFrameStyle(QFrame.NoFrame)
|
||||
self.filterOpt.setFrameStyle(QFrame.Shape.NoFrame)
|
||||
|
||||
# Assemble GUI
|
||||
# ============
|
||||
@@ -382,10 +381,10 @@ class _FilterTab(NFixedPage):
|
||||
self.selectionBox.addLayout(self.modeBox)
|
||||
self.selectionBox.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.selectionWidget = QWidget()
|
||||
self.selectionWidget = QWidget(self)
|
||||
self.selectionWidget.setLayout(self.selectionBox)
|
||||
|
||||
self.mainSplit = QSplitter()
|
||||
self.mainSplit = QSplitter(self)
|
||||
self.mainSplit.addWidget(self.selectionWidget)
|
||||
self.mainSplit.addWidget(self.filterOpt)
|
||||
self.mainSplit.setCollapsible(0, False)
|
||||
@@ -704,7 +703,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
# Edit Form
|
||||
# =========
|
||||
|
||||
self.lblEditForm = QLabel(self.tr("Editing: {0}").format(self.tr("None")))
|
||||
self.lblEditForm = QLabel(self.tr("Editing: {0}").format(self.tr("None")), self)
|
||||
|
||||
self.editTextBox = QPlainTextEdit(self)
|
||||
self.editTextBox.setFixedHeight(5*iPx)
|
||||
@@ -760,12 +759,12 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.layoutMatrix.addWidget(self.layoutHeading, 0, 0, 1, 5)
|
||||
|
||||
# Title Layout
|
||||
self.mtxTitle = QLabel(self._build.getLabel("headings.fmtTitle"))
|
||||
self.mtxTitle = QLabel(self._build.getLabel("headings.fmtTitle"), self)
|
||||
self.centerTitle = NSwitch(self, height=iPx)
|
||||
self.breakTitle = NSwitch(self, height=iPx)
|
||||
lblCenterT = QLabel(self.tr("Centre"))
|
||||
lblCenterT = QLabel(self.tr("Centre"), self)
|
||||
lblCenterT.setIndent(sSp)
|
||||
lblBreakT = QLabel(self.tr("Page Break"))
|
||||
lblBreakT = QLabel(self.tr("Page Break"), self)
|
||||
lblBreakT.setIndent(sSp)
|
||||
|
||||
self.layoutMatrix.addWidget(self.mtxTitle, 1, 0)
|
||||
@@ -775,12 +774,12 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.layoutMatrix.addWidget(self.breakTitle, 1, 4)
|
||||
|
||||
# Chapter Layout
|
||||
self.mtxChapter = QLabel(self._build.getLabel("headings.fmtChapter"))
|
||||
self.mtxChapter = QLabel(self._build.getLabel("headings.fmtChapter"), self)
|
||||
self.centerChapter = NSwitch(self, height=iPx)
|
||||
self.breakChapter = NSwitch(self, height=iPx)
|
||||
lblCenterC = QLabel(self.tr("Centre"))
|
||||
lblCenterC = QLabel(self.tr("Centre"), self)
|
||||
lblCenterC.setIndent(sSp)
|
||||
lblBreakC = QLabel(self.tr("Page Break"))
|
||||
lblBreakC = QLabel(self.tr("Page Break"), self)
|
||||
lblBreakC.setIndent(sSp)
|
||||
|
||||
self.layoutMatrix.addWidget(self.mtxChapter, 2, 0)
|
||||
@@ -790,12 +789,12 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.layoutMatrix.addWidget(self.breakChapter, 2, 4)
|
||||
|
||||
# Scene Layout
|
||||
self.mtxScene = QLabel(self._build.getLabel("headings.fmtScene"))
|
||||
self.mtxScene = QLabel(self._build.getLabel("headings.fmtScene"), self)
|
||||
self.centerScene = NSwitch(self, height=iPx)
|
||||
self.breakScene = NSwitch(self, height=iPx)
|
||||
lblCenterS = QLabel(self.tr("Centre"))
|
||||
lblCenterS = QLabel(self.tr("Centre"), self)
|
||||
lblCenterS.setIndent(sSp)
|
||||
lblBreakS = QLabel(self.tr("Page Break"))
|
||||
lblBreakS = QLabel(self.tr("Page Break"), self)
|
||||
lblBreakS.setIndent(sSp)
|
||||
|
||||
self.layoutMatrix.addWidget(self.mtxScene, 3, 0)
|
||||
|
||||
@@ -26,8 +26,8 @@ from __future__ import annotations
|
||||
import math
|
||||
import logging
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QDialog, QDialogButtonBox, QFormLayout, QGridLayout,
|
||||
QHBoxLayout, QLabel, QSpinBox, QStackedWidget, QTreeWidget,
|
||||
@@ -41,7 +41,7 @@ from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrol
|
||||
from novelwriter.extensions.novelselector import NovelSelector
|
||||
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import QtAlignRight
|
||||
from novelwriter.types import QtAlignRight, QtDecoration, QtDialogClose
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -95,7 +95,7 @@ class GuiNovelDetails(QDialog):
|
||||
self.mainStack.addWidget(self.contentsPage)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
|
||||
self.buttonBox = QDialogButtonBox(QtDialogClose, self)
|
||||
self.buttonBox.rejected.connect(self.close)
|
||||
|
||||
# Assemble
|
||||
@@ -366,7 +366,7 @@ class _ContentsPage(NFixedPage):
|
||||
countFrom = options.getInt("GuiNovelDetails", "countFrom", 1)
|
||||
clearDouble = options.getBool("GuiNovelDetails", "clearDouble", True)
|
||||
|
||||
self.wpLabel = QLabel(self.tr("Words per page"))
|
||||
self.wpLabel = QLabel(self.tr("Words per page"), self)
|
||||
|
||||
self.wpValue = QSpinBox(self)
|
||||
self.wpValue.setMinimum(10)
|
||||
@@ -375,7 +375,7 @@ class _ContentsPage(NFixedPage):
|
||||
self.wpValue.setValue(wordsPerPage)
|
||||
self.wpValue.valueChanged.connect(self._populateTree)
|
||||
|
||||
self.poLabel = QLabel(self.tr("First page offset"))
|
||||
self.poLabel = QLabel(self.tr("First page offset"), self)
|
||||
|
||||
self.poValue = QSpinBox(self)
|
||||
self.poValue.setMinimum(1)
|
||||
@@ -384,7 +384,7 @@ class _ContentsPage(NFixedPage):
|
||||
self.poValue.setValue(countFrom)
|
||||
self.poValue.valueChanged.connect(self._populateTree)
|
||||
|
||||
self.dblLabel = QLabel(self.tr("Chapters on odd pages"))
|
||||
self.dblLabel = QLabel(self.tr("Chapters on odd pages"), self)
|
||||
|
||||
self.dblValue = NSwitch(self, height=iPx)
|
||||
self.dblValue.setChecked(clearDouble)
|
||||
@@ -485,7 +485,7 @@ class _ContentsPage(NFixedPage):
|
||||
if tTitle.strip() == "":
|
||||
tTitle = self.tr("Untitled")
|
||||
|
||||
newItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
|
||||
newItem.setData(self.C_TITLE, QtDecoration, hDec)
|
||||
newItem.setText(self.C_TITLE, tTitle)
|
||||
newItem.setText(self.C_WORDS, f"{wCount:n}")
|
||||
newItem.setText(self.C_PAGES, f"{pCount:n}")
|
||||
|
||||
@@ -25,19 +25,19 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QFont, QPaintEvent, QPainter, QPen
|
||||
from PyQt5.QtCore import (
|
||||
QAbstractListModel, QEvent, QModelIndex, QObject, QPoint, QSize, Qt,
|
||||
pyqtSignal, pyqtSlot
|
||||
)
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QFont, QPaintEvent, QPainter, QPen
|
||||
from PyQt5.QtWidgets import (
|
||||
QAction, QDialog, QFileDialog, QFormLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QListView, QMenu, QPushButton, QScrollArea, QShortcut, QStackedWidget,
|
||||
QStyle, QStyleOptionViewItem, QStyledItemDelegate, QVBoxLayout, QWidget,
|
||||
qApp
|
||||
QAction, QApplication, QDialog, QFileDialog, QFormLayout, QHBoxLayout,
|
||||
QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut,
|
||||
QStackedWidget, QStyleOptionViewItem, QStyledItemDelegate, QVBoxLayout,
|
||||
QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -49,7 +49,7 @@ from novelwriter.extensions.configlayout import NWrappedWidgetBox
|
||||
from novelwriter.extensions.modified import NIconToolButton, NSpinBox
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRightTop
|
||||
from novelwriter.types import QtAlignLeft, QtAlignRightTop, QtSelected
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -377,7 +377,7 @@ class _OpenProjectPage(QWidget):
|
||||
action.triggered.connect(self.openSelectedItem)
|
||||
action = ctxMenu.addAction(self.tr("Remove Project"))
|
||||
action.triggered.connect(self._deleteSelectedItem)
|
||||
ctxMenu.exec_(self.mapToGlobal(pos))
|
||||
ctxMenu.exec(self.mapToGlobal(pos))
|
||||
ctxMenu.deleteLater()
|
||||
return
|
||||
|
||||
@@ -411,11 +411,11 @@ class _ProjectListItem(QStyledItemDelegate):
|
||||
self._pPx = (mPx//2, 3*mPx//2, iPx + mPx, mPx, mPx + tPx) # Painter coordinates
|
||||
self._hPx = 2*mPx + tPx + fPx # Fixed height
|
||||
|
||||
self._tFont = qApp.font()
|
||||
self._tFont = QApplication.font()
|
||||
self._tFont.setPointSizeF(1.2*fPt)
|
||||
self._tFont.setWeight(QFont.Weight.Bold)
|
||||
|
||||
self._dFont = qApp.font()
|
||||
self._dFont = QApplication.font()
|
||||
self._dFont.setPointSizeF(fPt)
|
||||
self._dPen = QPen(SHARED.theme.helpText)
|
||||
|
||||
@@ -431,9 +431,9 @@ class _ProjectListItem(QStyledItemDelegate):
|
||||
ix, iy, x, y1, y2 = self._pPx
|
||||
|
||||
painter.save()
|
||||
if opt.state & QStyle.StateFlag.State_Selected == QStyle.StateFlag.State_Selected:
|
||||
if opt.state & QtSelected == QtSelected:
|
||||
painter.setOpacity(0.25)
|
||||
painter.fillRect(rect, qApp.palette().highlight())
|
||||
painter.fillRect(rect, QApplication.palette().highlight())
|
||||
painter.setOpacity(1.0)
|
||||
|
||||
painter.drawPixmap(ix, rect.top() + iy, self._icon)
|
||||
@@ -682,10 +682,10 @@ class _NewProjectForm(QWidget):
|
||||
# ========
|
||||
|
||||
self.extraBox = QVBoxLayout()
|
||||
self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Chapters and Scenes"))))
|
||||
self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Chapters and Scenes")), self))
|
||||
self.extraBox.addLayout(self.novelForm)
|
||||
self.extraBox.addSpacing(sPx)
|
||||
self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Project Notes"))))
|
||||
self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Project Notes")), self))
|
||||
self.extraBox.addLayout(self.notesForm)
|
||||
self.extraBox.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
@@ -694,7 +694,7 @@ class _NewProjectForm(QWidget):
|
||||
self.extraWidget.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.formBox = QVBoxLayout()
|
||||
self.formBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Create New Project"))))
|
||||
self.formBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Create New Project")), self))
|
||||
self.formBox.addLayout(self.projectForm)
|
||||
self.formBox.addSpacing(sPx)
|
||||
self.formBox.addWidget(self.extraWidget)
|
||||
@@ -738,7 +738,7 @@ class _NewProjectForm(QWidget):
|
||||
"""Select a project folder."""
|
||||
if projDir := QFileDialog.getExistingDirectory(
|
||||
self, self.tr("Select Project Folder"),
|
||||
str(self._basePath), options=QFileDialog.ShowDirsOnly
|
||||
str(self._basePath), options=QFileDialog.Option.ShowDirsOnly
|
||||
):
|
||||
self._basePath = Path(projDir)
|
||||
self._updateProjPath()
|
||||
@@ -813,7 +813,7 @@ class _PopLeftDirectionMenu(QMenu):
|
||||
|
||||
def event(self, event: QEvent) -> bool:
|
||||
"""Overload the show event and move the menu popup location."""
|
||||
if event.type() == QEvent.Show:
|
||||
if event.type() == QEvent.Type.Show:
|
||||
if isinstance(parent := self.parent(), QWidget):
|
||||
offset = QPoint(parent.width() - self.width(), parent.height())
|
||||
self.move(parent.mapToGlobal(offset))
|
||||
|
||||
@@ -29,11 +29,12 @@ import logging
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtGui import QCloseEvent, QPixmap, QCursor
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor, QPixmap
|
||||
from PyQt5.QtWidgets import (
|
||||
qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
|
||||
QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout
|
||||
QAction, QApplication, QDialog, QDialogButtonBox, QFileDialog, QGridLayout,
|
||||
QGroupBox, QHBoxLayout, QLabel, QMenu, QSpinBox, QTreeWidget,
|
||||
QTreeWidgetItem
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -41,7 +42,10 @@ from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax
|
||||
from novelwriter.constants import nwConst
|
||||
from novelwriter.error import formatException
|
||||
from novelwriter.extensions.switch import NSwitch
|
||||
from novelwriter.types import QtAlignLeftMiddle, QtAlignRight, QtAlignRightMiddle
|
||||
from novelwriter.types import (
|
||||
QtAlignLeftMiddle, QtAlignRight, QtAlignRightMiddle, QtDecoration,
|
||||
QtDialogClose, QtRoleAction
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -101,7 +105,7 @@ class GuiWritingStats(QDialog):
|
||||
pOptions.getInt("GuiWritingStats", "widthCol3", 80)
|
||||
)
|
||||
|
||||
self.listBox = QTreeWidget()
|
||||
self.listBox = QTreeWidget(self)
|
||||
self.listBox.setHeaderLabels([
|
||||
self.tr("Session Start"),
|
||||
self.tr("Length"),
|
||||
@@ -121,10 +125,11 @@ class GuiWritingStats(QDialog):
|
||||
hHeader.setTextAlignment(self.C_IDLE, QtAlignRight)
|
||||
hHeader.setTextAlignment(self.C_COUNT, QtAlignRight)
|
||||
|
||||
sDec = Qt.SortOrder.DescendingOrder
|
||||
sAsc = Qt.SortOrder.AscendingOrder
|
||||
sortCol = minmax(pOptions.getInt("GuiWritingStats", "sortCol", 0), 0, 2)
|
||||
sortOrder = checkIntTuple(
|
||||
pOptions.getInt("GuiWritingStats", "sortOrder", Qt.DescendingOrder),
|
||||
(Qt.AscendingOrder, Qt.DescendingOrder), Qt.DescendingOrder
|
||||
pOptions.getInt("GuiWritingStats", "sortOrder", sDec), (sAsc, sDec), sDec
|
||||
)
|
||||
self.listBox.sortByColumn(sortCol, sortOrder) # type: ignore
|
||||
self.listBox.setSortingEnabled(True)
|
||||
@@ -140,36 +145,36 @@ class GuiWritingStats(QDialog):
|
||||
self.infoForm = QGridLayout(self)
|
||||
self.infoBox.setLayout(self.infoForm)
|
||||
|
||||
self.labelTotal = QLabel(formatTime(0))
|
||||
self.labelTotal = QLabel(formatTime(0), self)
|
||||
self.labelTotal.setFont(SHARED.theme.guiFontFixed)
|
||||
self.labelTotal.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
self.labelIdleT = QLabel(formatTime(0))
|
||||
self.labelIdleT = QLabel(formatTime(0), self)
|
||||
self.labelIdleT.setFont(SHARED.theme.guiFontFixed)
|
||||
self.labelIdleT.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
self.labelFilter = QLabel(formatTime(0))
|
||||
self.labelFilter = QLabel(formatTime(0), self)
|
||||
self.labelFilter.setFont(SHARED.theme.guiFontFixed)
|
||||
self.labelFilter.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
self.novelWords = QLabel("0")
|
||||
self.novelWords = QLabel("0", self)
|
||||
self.novelWords.setFont(SHARED.theme.guiFontFixed)
|
||||
self.novelWords.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
self.notesWords = QLabel("0")
|
||||
self.notesWords = QLabel("0", self)
|
||||
self.notesWords.setFont(SHARED.theme.guiFontFixed)
|
||||
self.notesWords.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
self.totalWords = QLabel("0")
|
||||
self.totalWords = QLabel("0", self)
|
||||
self.totalWords.setFont(SHARED.theme.guiFontFixed)
|
||||
self.totalWords.setAlignment(QtAlignRightMiddle)
|
||||
|
||||
lblTTime = QLabel(self.tr("Total Time:"))
|
||||
lblITime = QLabel(self.tr("Idle Time:"))
|
||||
lblFTime = QLabel(self.tr("Filtered Time:"))
|
||||
lblNvCount = QLabel(self.tr("Novel Word Count:"))
|
||||
lblNtCount = QLabel(self.tr("Notes Word Count:"))
|
||||
lblTtCount = QLabel(self.tr("Total Word Count:"))
|
||||
lblTTime = QLabel(self.tr("Total Time:"), self)
|
||||
lblITime = QLabel(self.tr("Idle Time:"), self)
|
||||
lblFTime = QLabel(self.tr("Filtered Time:"), self)
|
||||
lblNvCount = QLabel(self.tr("Novel Word Count:"), self)
|
||||
lblNtCount = QLabel(self.tr("Notes Word Count:"), self)
|
||||
lblTtCount = QLabel(self.tr("Total Word Count:"), self)
|
||||
|
||||
self.infoForm.addWidget(lblTTime, 0, 0)
|
||||
self.infoForm.addWidget(lblITime, 1, 0)
|
||||
@@ -230,12 +235,12 @@ class GuiWritingStats(QDialog):
|
||||
)
|
||||
self.showIdleTime.clicked.connect(self._updateListBox)
|
||||
|
||||
self.filterForm.addWidget(QLabel(self.tr("Count novel files")), 0, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Count note files")), 1, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Hide zero word count")), 2, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Hide negative word count")), 3, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Group entries by day")), 4, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Show idle time")), 5, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Count novel files"), self), 0, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Count note files"), self), 1, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Hide zero word count"), self), 2, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Hide negative word count"), self), 3, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Group entries by day"), self), 4, 0)
|
||||
self.filterForm.addWidget(QLabel(self.tr("Show idle time"), self), 5, 0)
|
||||
self.filterForm.addWidget(self.incNovel, 0, 1)
|
||||
self.filterForm.addWidget(self.incNotes, 1, 1)
|
||||
self.filterForm.addWidget(self.hideZeros, 2, 1)
|
||||
@@ -256,17 +261,17 @@ class GuiWritingStats(QDialog):
|
||||
|
||||
self.optsBox = QHBoxLayout()
|
||||
self.optsBox.addStretch(1)
|
||||
self.optsBox.addWidget(QLabel(self.tr("Word count cap for the histogram")), 0)
|
||||
self.optsBox.addWidget(QLabel(self.tr("Word count cap for the histogram"), self), 0)
|
||||
self.optsBox.addWidget(self.histMax, 0)
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox()
|
||||
self.buttonBox = QDialogButtonBox(self)
|
||||
self.buttonBox.rejected.connect(self._doClose)
|
||||
|
||||
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
|
||||
self.btnClose = self.buttonBox.addButton(QtDialogClose)
|
||||
self.btnClose.setAutoDefault(False)
|
||||
|
||||
self.btnSave = self.buttonBox.addButton(self.tr("Save As"), QDialogButtonBox.ActionRole)
|
||||
self.btnSave = self.buttonBox.addButton(self.tr("Save As"), QtRoleAction)
|
||||
self.btnSave.setAutoDefault(False)
|
||||
|
||||
self.saveMenu = QMenu(self)
|
||||
@@ -301,10 +306,10 @@ class GuiWritingStats(QDialog):
|
||||
|
||||
def populateGUI(self) -> None:
|
||||
"""Populate list box with data from the log file."""
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
self._loadLogFile()
|
||||
self._updateListBox()
|
||||
qApp.restoreOverrideCursor()
|
||||
QApplication.restoreOverrideCursor()
|
||||
return
|
||||
|
||||
##
|
||||
@@ -570,6 +575,8 @@ class GuiWritingStats(QDialog):
|
||||
pcTotal = wcTotal
|
||||
|
||||
# Populate the list
|
||||
mTrans = Qt.TransformationMode.FastTransformation
|
||||
mAspect = Qt.AspectRatioMode.IgnoreAspectRatio
|
||||
showIdleTime = self.showIdleTime.isChecked()
|
||||
for _, sStart, sDiff, nWords, _, _, sIdle in self.filterData:
|
||||
|
||||
@@ -588,11 +595,9 @@ class GuiWritingStats(QDialog):
|
||||
if nWords > 0 and listMax > 0:
|
||||
wBar = self.barImage.scaled(
|
||||
int(200*min(nWords, histMax)/listMax),
|
||||
self.barHeight,
|
||||
Qt.IgnoreAspectRatio,
|
||||
Qt.FastTransformation
|
||||
self.barHeight, mAspect, mTrans
|
||||
)
|
||||
newItem.setData(self.C_BAR, Qt.DecorationRole, wBar)
|
||||
newItem.setData(self.C_BAR, QtDecoration, wBar)
|
||||
|
||||
newItem.setTextAlignment(self.C_LENGTH, QtAlignRight)
|
||||
newItem.setTextAlignment(self.C_IDLE, QtAlignRight)
|
||||
|
||||
@@ -24,6 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from __future__ import annotations
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QColor, QPainter, QTextCursor
|
||||
from PyQt5.QtWidgets import QDialogButtonBox, QStyle
|
||||
|
||||
# Qt Alignment Flags
|
||||
|
||||
@@ -41,3 +43,48 @@ QtAlignRightBase = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignBaseline
|
||||
QtAlignRightMiddle = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
|
||||
QtAlignRightTop = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
|
||||
QtAlignTop = Qt.AlignmentFlag.AlignTop
|
||||
|
||||
# Qt Painter Types
|
||||
|
||||
QtTransparent = QColor(0, 0, 0, 0)
|
||||
QtNoBrush = Qt.BrushStyle.NoBrush
|
||||
QtNoPen = Qt.PenStyle.NoPen
|
||||
QtRoundCap = Qt.PenCapStyle.RoundCap
|
||||
QtSolidLine = Qt.PenStyle.SolidLine
|
||||
QtPaintAnitAlias = QPainter.RenderHint.Antialiasing
|
||||
QtMouseOver = QStyle.StateFlag.State_MouseOver
|
||||
QtSelected = QStyle.StateFlag.State_Selected
|
||||
|
||||
# Qt Tree and Table Types
|
||||
|
||||
QtDecoration = Qt.ItemDataRole.DecorationRole
|
||||
QtUserRole = Qt.ItemDataRole.UserRole
|
||||
|
||||
# Keyboard and Mouse Buttons
|
||||
|
||||
QtModCtrl = Qt.KeyboardModifier.ControlModifier
|
||||
QtModeNone = Qt.KeyboardModifier.NoModifier
|
||||
QtModShift = Qt.KeyboardModifier.ShiftModifier
|
||||
QtMouseLeft = Qt.MouseButton.LeftButton
|
||||
QtMouseMiddle = Qt.MouseButton.MiddleButton
|
||||
|
||||
# Dialog Button Box Types
|
||||
|
||||
QtDialogApply = QDialogButtonBox.StandardButton.Apply
|
||||
QtDialogCancel = QDialogButtonBox.StandardButton.Cancel
|
||||
QtDialogClose = QDialogButtonBox.StandardButton.Close
|
||||
QtDialogOk = QDialogButtonBox.StandardButton.Ok
|
||||
QtDialogReset = QDialogButtonBox.StandardButton.Reset
|
||||
QtDialogSave = QDialogButtonBox.StandardButton.Save
|
||||
|
||||
QtRoleAccept = QDialogButtonBox.ButtonRole.AcceptRole
|
||||
QtRoleAction = QDialogButtonBox.ButtonRole.ActionRole
|
||||
QtRoleApply = QDialogButtonBox.ButtonRole.ApplyRole
|
||||
QtRoleReject = QDialogButtonBox.ButtonRole.RejectRole
|
||||
|
||||
# Cursor Types
|
||||
|
||||
QtKeepAnchor = QTextCursor.MoveMode.KeepAnchor
|
||||
QtMoveAnchor = QTextCursor.MoveMode.MoveAnchor
|
||||
QtMoveLeft = QTextCursor.MoveOperation.Left
|
||||
QtMoveRight = QTextCursor.MoveOperation.Right
|
||||
|
||||
+2
-2
@@ -142,7 +142,7 @@ def projPath(fncPath):
|
||||
@pytest.fixture(scope="function")
|
||||
def mockGUI(qtbot, monkeypatch):
|
||||
"""Create a mock instance of novelWriter's main GUI class."""
|
||||
monkeypatch.setattr(QMessageBox, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "result", lambda *a: QMessageBox.Yes)
|
||||
gui = MockGuiMain()
|
||||
theme = MockTheme()
|
||||
@@ -154,7 +154,7 @@ def mockGUI(qtbot, monkeypatch):
|
||||
@pytest.fixture(scope="function")
|
||||
def nwGUI(qtbot, monkeypatch, functionFixture):
|
||||
"""Create an instance of the novelWriter GUI."""
|
||||
monkeypatch.setattr(QMessageBox, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "result", lambda *a: QMessageBox.Yes)
|
||||
|
||||
nwGUI = main(["--testmode", f"--config={_TMP_CONF}", f"--data={_TMP_CONF}"])
|
||||
|
||||
@@ -36,13 +36,13 @@ def testBaseError_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
nwErr.show()
|
||||
|
||||
# Invalid Error Message
|
||||
nwErr.setMessage(Exception, "Faulty Error", 123)
|
||||
nwErr.setMessage(Exception, "Faulty Error", 123) # type: ignore
|
||||
assert nwErr.msgBody.toPlainText() == "Failed to generate error report ..."
|
||||
|
||||
# Valid Error Message
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", lambda: "1.2.3")
|
||||
nwErr.setMessage(Exception, "Fine Error", None)
|
||||
nwErr.setMessage(Exception, "Fine Error", None) # type: ignore
|
||||
message = nwErr.msgBody.toPlainText()
|
||||
assert message != ""
|
||||
assert "Fine Error" in message
|
||||
@@ -52,7 +52,7 @@ def testBaseError_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
# No kernel version retrieved
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", causeException)
|
||||
nwErr.setMessage(Exception, "Almost Fine Error", None)
|
||||
nwErr.setMessage(Exception, "Almost Fine Error", None) # type: ignore
|
||||
message = nwErr.msgBody.toPlainText()
|
||||
assert message != ""
|
||||
assert "(Unknown)" in message
|
||||
@@ -66,36 +66,36 @@ def testBaseError_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseError_Handler(qtbot, monkeypatch, nwGUI):
|
||||
"""Test the error handler. This test doesn'thave any asserts, but it
|
||||
checks that the error handler handles potential exceptions. The test
|
||||
will fail if exceptions are not handled.
|
||||
"""Test the error handler. This test doesn't have any asserts, but
|
||||
it checks that the error handler handles potential exceptions. The
|
||||
test will fail if exceptions are not handled.
|
||||
"""
|
||||
# Normal shutdown
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(NWErrorMessage, "exec_", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.exit", lambda *a: None)
|
||||
exceptionHandler(Exception, "Error Message", None)
|
||||
mp.setattr(NWErrorMessage, "exec", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.exit", lambda *a: None)
|
||||
exceptionHandler(Exception, "Error Message", None) # type: ignore
|
||||
|
||||
# Should not crash when no GUI is found
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(NWErrorMessage, "exec_", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.exit", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.topLevelWidgets", lambda: [])
|
||||
exceptionHandler(Exception, "Error Message", None)
|
||||
mp.setattr(NWErrorMessage, "exec", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.exit", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.topLevelWidgets", lambda: [])
|
||||
exceptionHandler(Exception, "Error Message", None) # type: ignore
|
||||
|
||||
# Should handle qApp failing
|
||||
# Should handle QApplication failing
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(NWErrorMessage, "exec_", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.exit", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.topLevelWidgets", causeException)
|
||||
exceptionHandler(Exception, "Error Message", None)
|
||||
mp.setattr(NWErrorMessage, "exec", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.exit", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.topLevelWidgets", causeException)
|
||||
exceptionHandler(Exception, "Error Message", None) # type: ignore
|
||||
|
||||
# Should handle failing to close main GUI
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(NWErrorMessage, "exec_", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.qApp.exit", lambda *a: None)
|
||||
mp.setattr(NWErrorMessage, "exec", lambda *a: None)
|
||||
mp.setattr("PyQt5.QtWidgets.QApplication.exit", lambda *a: None)
|
||||
mp.setattr(nwGUI, "closeMain", causeException)
|
||||
exceptionHandler(Exception, "Error Message", None)
|
||||
exceptionHandler(Exception, "Error Message", None) # type: ignore
|
||||
|
||||
nwGUI.closeMain()
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ def testBaseInit_Launch(caplog, monkeypatch, fncPath):
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *a: 0)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
|
||||
with pytest.raises(SystemExit) as ex:
|
||||
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||
assert ex.value.code == 0
|
||||
@@ -148,7 +148,7 @@ def testBaseInit_Imports(caplog, monkeypatch, fncPath):
|
||||
"""Check import error handling."""
|
||||
monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *a: 0)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.__init__", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.resize", lambda *a: None)
|
||||
monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.showMessage", lambda *a: None)
|
||||
|
||||
@@ -129,7 +129,7 @@ def testBaseSharedData_Projects(monkeypatch, caplog, fncPath):
|
||||
@pytest.mark.base
|
||||
def testBaseSharedData_Alerts(qtbot, monkeypatch, caplog):
|
||||
"""Test SharedData class alert helper functions."""
|
||||
monkeypatch.setattr(QMessageBox, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "result", lambda *a: QMessageBox.Yes)
|
||||
|
||||
shared = SharedData()
|
||||
|
||||
@@ -32,7 +32,7 @@ from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
@pytest.mark.gui
|
||||
def testDlgOther_QuoteSelect(qtbot, monkeypatch, nwGUI):
|
||||
"""Test the quote symbols dialog."""
|
||||
monkeypatch.setattr(GuiQuoteSelect, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiQuoteSelect, "exec", lambda *a: None)
|
||||
|
||||
nwQuot = GuiQuoteSelect(nwGUI)
|
||||
nwQuot.show()
|
||||
@@ -47,7 +47,7 @@ def testDlgOther_QuoteSelect(qtbot, monkeypatch, nwGUI):
|
||||
assert nwQuot.previewLabel.text() == lastItem
|
||||
|
||||
nwQuot.accept()
|
||||
assert nwQuot.result() == QDialog.Accepted
|
||||
assert nwQuot.result() == QDialog.DialogCode.Accepted
|
||||
assert nwQuot.selectedQuote == lastItem
|
||||
nwQuot.close()
|
||||
|
||||
@@ -68,16 +68,16 @@ def testDlgOther_QuoteSelect(qtbot, monkeypatch, nwGUI):
|
||||
@pytest.mark.gui
|
||||
def testDlgOther_EditLabel(qtbot, monkeypatch):
|
||||
"""Test the label editor dialog."""
|
||||
monkeypatch.setattr(GuiEditLabel, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiEditLabel, "exec", lambda *a: None)
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.Accepted)
|
||||
mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.DialogCode.Accepted)
|
||||
newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") # type: ignore
|
||||
assert dlgOk is True
|
||||
assert newLabel == "Hello World"
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.Rejected)
|
||||
mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.DialogCode.Rejected)
|
||||
newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") # type: ignore
|
||||
assert dlgOk is False
|
||||
assert newLabel == "Hello World"
|
||||
|
||||
@@ -27,6 +27,7 @@ from tools import buildTestProject, C
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from novelwriter.dialogs.docmerge import GuiDocMerge
|
||||
from novelwriter.types import QtUserRole
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -53,11 +54,11 @@ def testDlgMerge_Main(qtbot, nwGUI, projPath, mockRnd):
|
||||
itemOne = nwMerge.listBox.item(0)
|
||||
itemTwo = nwMerge.listBox.item(1)
|
||||
|
||||
assert itemOne.data(Qt.ItemDataRole.UserRole) == C.hChapterDoc
|
||||
assert itemTwo.data(Qt.ItemDataRole.UserRole) == C.hSceneDoc
|
||||
assert itemOne.data(QtUserRole) == C.hChapterDoc
|
||||
assert itemTwo.data(QtUserRole) == C.hSceneDoc
|
||||
|
||||
assert itemOne.checkState() == Qt.Checked
|
||||
assert itemTwo.checkState() == Qt.Checked
|
||||
assert itemOne.checkState() == Qt.CheckState.Checked
|
||||
assert itemTwo.checkState() == Qt.CheckState.Checked
|
||||
|
||||
data = nwMerge.getData()
|
||||
assert data["sHandle"] == C.hChapterDir
|
||||
@@ -66,7 +67,7 @@ def testDlgMerge_Main(qtbot, nwGUI, projPath, mockRnd):
|
||||
assert data["finalItems"] == [C.hChapterDoc, C.hSceneDoc]
|
||||
|
||||
# Uncheck second item and toggle trash switch
|
||||
itemTwo.setCheckState(Qt.Unchecked)
|
||||
itemTwo.setCheckState(Qt.CheckState.Unchecked)
|
||||
nwMerge.trashSwitch.setChecked(True)
|
||||
|
||||
data = nwMerge.getData()
|
||||
|
||||
@@ -24,12 +24,13 @@ import pytest
|
||||
|
||||
from PyQt5.QtGui import QFontDatabase, QKeyEvent
|
||||
from PyQt5.QtCore import QEvent, Qt
|
||||
from PyQt5.QtWidgets import QAction, QDialogButtonBox, QFileDialog, QFontDialog
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog, QFontDialog
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwConst, nwUnicode
|
||||
from novelwriter.dialogs.preferences import GuiPreferences
|
||||
from novelwriter.dialogs.quotes import GuiQuoteSelect
|
||||
from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave, QtModeNone
|
||||
|
||||
KEY_DELAY = 1
|
||||
|
||||
@@ -38,7 +39,7 @@ KEY_DELAY = 1
|
||||
def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
"""Test the preferences dialog loading."""
|
||||
monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: [("en", "English [en]")])
|
||||
monkeypatch.setattr(GuiPreferences, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiPreferences, "exec", lambda *a: None)
|
||||
|
||||
# Load GUI with standard values
|
||||
nwGUI.mainMenu.aPreferences.activate(QAction.ActionEvent.Trigger)
|
||||
@@ -121,27 +122,27 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI):
|
||||
# Check Apply Button
|
||||
prefs.show()
|
||||
with qtbot.waitSignal(prefs.newPreferencesReady) as signal:
|
||||
prefs.buttonBox.button(QDialogButtonBox.StandardButton.Apply).click()
|
||||
prefs.buttonBox.button(QtDialogApply).click()
|
||||
assert signal.args == [False, False, False, False]
|
||||
|
||||
# Check Save Button
|
||||
prefs.show()
|
||||
with qtbot.waitSignal(prefs.newPreferencesReady) as signal:
|
||||
with qtbot.waitSignal(prefs.finished) as status:
|
||||
prefs.buttonBox.button(QDialogButtonBox.StandardButton.Save).click()
|
||||
prefs.buttonBox.button(QtDialogSave).click()
|
||||
assert signal.args == [False, False, False, False]
|
||||
assert status.args == [nwConst.DLG_FINISHED]
|
||||
|
||||
# Check Close Button
|
||||
prefs.show()
|
||||
with qtbot.waitSignal(prefs.finished) as status:
|
||||
prefs.buttonBox.button(QDialogButtonBox.StandardButton.Close).click()
|
||||
prefs.buttonBox.button(QtDialogClose).click()
|
||||
assert status.args == [nwConst.DLG_FINISHED]
|
||||
|
||||
# Close Using Escape Key
|
||||
prefs.show()
|
||||
with qtbot.waitSignal(prefs.finished) as status:
|
||||
event = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_Escape, Qt.KeyboardModifier.NoModifier)
|
||||
event = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_Escape, QtModeNone)
|
||||
prefs.keyPressEvent(event)
|
||||
assert status.args == [nwConst.DLG_FINISHED]
|
||||
|
||||
@@ -332,7 +333,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QFontDatabase, "families", lambda *a: ["TestFont"])
|
||||
with qtbot.waitSignal(prefs.newPreferencesReady) as signal:
|
||||
prefs.buttonBox.button(QDialogButtonBox.StandardButton.Apply).click()
|
||||
prefs.buttonBox.button(QtDialogApply).click()
|
||||
assert signal.args == [True, True, True, True]
|
||||
|
||||
# Check Settings
|
||||
|
||||
@@ -24,14 +24,15 @@ import pytest
|
||||
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QColor
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QColor
|
||||
from PyQt5.QtWidgets import QDialog, QAction, QColorDialog
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.enum import nwItemType
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
||||
from novelwriter.enum import nwItemType
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
KEY_DELAY = 1
|
||||
|
||||
@@ -42,8 +43,8 @@ def testDlgProjSettings_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
test, but are instead tested in the individual tab tests.
|
||||
"""
|
||||
# Block the GUI blocking thread
|
||||
monkeypatch.setattr(GuiProjectSettings, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiProjectSettings, "result", lambda *a: QDialog.Accepted)
|
||||
monkeypatch.setattr(GuiProjectSettings, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(GuiProjectSettings, "result", lambda *a: QDialog.DialogCode.Accepted)
|
||||
|
||||
# Check that we cannot open when there is no project
|
||||
nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger)
|
||||
@@ -188,13 +189,13 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, projPath, mockRn
|
||||
# Can't delete the first item (it's in use)
|
||||
status.listBox.clearSelection()
|
||||
status.listBox.setCurrentItem(status.listBox.topLevelItem(0))
|
||||
qtbot.mouseClick(status.delButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(status.delButton, QtMouseLeft)
|
||||
assert status.listBox.topLevelItemCount() == 4
|
||||
|
||||
# Can delete the second item
|
||||
status.listBox.clearSelection()
|
||||
status.listBox.setCurrentItem(status.listBox.topLevelItem(1))
|
||||
qtbot.mouseClick(status.delButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(status.delButton, QtMouseLeft)
|
||||
assert status.listBox.topLevelItemCount() == 3
|
||||
|
||||
# Add a new item
|
||||
@@ -270,21 +271,21 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, projPath, mockRn
|
||||
# Delete unused entry
|
||||
importance.listBox.clearSelection()
|
||||
importance.listBox.setCurrentItem(importance.listBox.topLevelItem(1))
|
||||
qtbot.mouseClick(importance.delButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(importance.delButton, QtMouseLeft)
|
||||
assert importance.listBox.topLevelItemCount() == 3
|
||||
|
||||
# Add a new entry
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40))
|
||||
qtbot.mouseClick(importance.addButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(importance.addButton, QtMouseLeft)
|
||||
importance.listBox.clearSelection()
|
||||
importance.listBox.setCurrentItem(importance.listBox.topLevelItem(3))
|
||||
for _ in range(8):
|
||||
qtbot.keyClick(importance.editName, Qt.Key_Backspace, delay=KEY_DELAY)
|
||||
qtbot.keyClick(importance.editName, Qt.Key.Key_Backspace, delay=KEY_DELAY)
|
||||
for c in "Final":
|
||||
qtbot.keyClick(importance.editName, c, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(importance.colButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(importance.saveButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(importance.colButton, QtMouseLeft)
|
||||
qtbot.mouseClick(importance.saveButton, QtMouseLeft)
|
||||
assert importance.listBox.topLevelItemCount() == 4
|
||||
|
||||
assert importance.wasChanged is True
|
||||
@@ -367,7 +368,7 @@ def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
assert replace.listBox.topLevelItemCount() == 2
|
||||
|
||||
# Create a new entry
|
||||
qtbot.mouseClick(replace.addButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(replace.addButton, QtMouseLeft)
|
||||
assert replace.listBox.topLevelItemCount() == 3
|
||||
assert replace.listBox.topLevelItem(2).text(0) == "<keyword3>" # type: ignore
|
||||
assert replace.listBox.topLevelItem(2).text(1) == "" # type: ignore
|
||||
@@ -380,13 +381,13 @@ def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
replace.editValue.setText("")
|
||||
for c in "With This Stuff ":
|
||||
qtbot.keyClick(replace.editValue, c, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(replace.saveButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(replace.saveButton, QtMouseLeft)
|
||||
assert replace.listBox.topLevelItem(2).text(0) == "<This>" # type: ignore
|
||||
assert replace.listBox.topLevelItem(2).text(1) == "With This Stuff " # type: ignore
|
||||
|
||||
# Create a new entry again
|
||||
replace.listBox.clearSelection()
|
||||
qtbot.mouseClick(replace.addButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(replace.addButton, QtMouseLeft)
|
||||
assert replace.listBox.topLevelItemCount() == 4
|
||||
|
||||
# The list is sorted, so we must find it
|
||||
@@ -399,7 +400,7 @@ def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
# Then delete the new item
|
||||
replace.listBox.setCurrentItem(replace.listBox.topLevelItem(newIdx))
|
||||
qtbot.mouseClick(replace.delButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(replace.delButton, QtMouseLeft)
|
||||
assert replace.listBox.topLevelItemCount() == 3
|
||||
|
||||
# Check Project
|
||||
|
||||
@@ -38,8 +38,8 @@ def testDlgWordList_Dialog(qtbot, monkeypatch, nwGUI, fncPath, projPath):
|
||||
"""test the word list editor."""
|
||||
buildTestProject(nwGUI, projPath)
|
||||
|
||||
monkeypatch.setattr(GuiWordList, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiWordList, "result", lambda *a: QDialog.Accepted)
|
||||
monkeypatch.setattr(GuiWordList, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(GuiWordList, "result", lambda *a: QDialog.DialogCode.Accepted)
|
||||
monkeypatch.setattr(GuiWordList, "accept", lambda *a: None)
|
||||
|
||||
# Open project
|
||||
|
||||
@@ -27,6 +27,7 @@ from PyQt5.QtCore import QEvent, QObject, QPoint, Qt
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
|
||||
from novelwriter.extensions.eventfilters import WheelEventFilter
|
||||
from novelwriter.types import QtModShift
|
||||
|
||||
|
||||
class MockWidget(QWidget):
|
||||
@@ -50,7 +51,7 @@ def testExtEventFilters_WheelEventFilter():
|
||||
assert widget.count == 0
|
||||
|
||||
# Sending a key event does nothing
|
||||
event = QKeyEvent(QEvent.KeyPress, 1, Qt.ShiftModifier)
|
||||
event = QKeyEvent(QEvent.Type.KeyPress, 1, QtModShift)
|
||||
eFilter.eventFilter(obj, event)
|
||||
assert widget.count == 0
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from tools import C, buildTestProject
|
||||
from mocked import causeOSError
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QClipboard, QTextBlock, QTextCursor, QTextOption
|
||||
from PyQt5.QtCore import QThreadPool, Qt
|
||||
from PyQt5.QtWidgets import QAction, QMenu, qApp
|
||||
from PyQt5.QtGui import QClipboard, QTextBlock, QTextCursor, QTextOption
|
||||
from PyQt5.QtWidgets import QAction, QApplication, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwKeyWords, nwUnicode
|
||||
@@ -37,7 +37,7 @@ from novelwriter.enum import (
|
||||
)
|
||||
from novelwriter.gui.doceditor import GuiDocEditor, GuiDocToolBar
|
||||
from novelwriter.text.counting import standardCounter
|
||||
from novelwriter.types import QtAlignJustify, QtAlignLeft
|
||||
from novelwriter.types import QtAlignJustify, QtAlignLeft, QtKeepAnchor, QtMouseLeft, QtMoveRight
|
||||
|
||||
KEY_DELAY = 1
|
||||
|
||||
@@ -95,7 +95,7 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
||||
|
||||
# Select item from header
|
||||
with qtbot.waitSignal(nwGUI.docEditor.requestProjectItemSelected, timeout=1000) as signal:
|
||||
qtbot.mouseClick(nwGUI.docEditor.docHeader, Qt.MouseButton.LeftButton)
|
||||
qtbot.mouseClick(nwGUI.docEditor.docHeader, QtMouseLeft)
|
||||
assert signal.args == [nwGUI.docEditor.docHeader._docHandle, True]
|
||||
|
||||
# Close from header
|
||||
@@ -109,7 +109,7 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
||||
|
||||
# Select item from header
|
||||
with qtbot.waitSignal(nwGUI.docEditor.requestProjectItemSelected, timeout=1000) as signal:
|
||||
qtbot.mouseClick(nwGUI.docEditor.docHeader, Qt.MouseButton.LeftButton)
|
||||
qtbot.mouseClick(nwGUI.docEditor.docHeader, QtMouseLeft)
|
||||
assert signal.args == ["", True]
|
||||
|
||||
# qtbot.stop()
|
||||
@@ -244,7 +244,7 @@ def testGuiEditor_MetaData(qtbot, nwGUI, projPath, mockRnd):
|
||||
@pytest.mark.gui
|
||||
def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
"""Test the editor context menu."""
|
||||
monkeypatch.setattr(QMenu, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMenu, "exec", lambda *a: None)
|
||||
|
||||
buildTestProject(nwGUI, projPath)
|
||||
assert nwGUI.openDocument(C.hSceneDoc) is True
|
||||
@@ -361,14 +361,14 @@ def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
assert actions == [
|
||||
"Cut", "Copy", "Paste", "Select All", "Select Word", "Select Paragraph"
|
||||
]
|
||||
qApp.clipboard().clear()
|
||||
QApplication.clipboard().clear()
|
||||
ctxMenu.actions()[1].trigger()
|
||||
assert qApp.clipboard().text(QClipboard.Mode.Clipboard) == "text"
|
||||
assert QApplication.clipboard().text(QClipboard.Mode.Clipboard) == "text"
|
||||
|
||||
# Cut Text
|
||||
qApp.clipboard().clear()
|
||||
QApplication.clipboard().clear()
|
||||
ctxMenu.actions()[0].trigger()
|
||||
assert qApp.clipboard().text(QClipboard.Mode.Clipboard) == "text"
|
||||
assert QApplication.clipboard().text(QClipboard.Mode.Clipboard) == "text"
|
||||
assert "text" not in docEditor.getText()
|
||||
|
||||
# Paste Text
|
||||
@@ -400,7 +400,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
||||
# Select/Cut/Copy/Paste/Undo/Redo
|
||||
# ===============================
|
||||
|
||||
qApp.clipboard().clear()
|
||||
QApplication.clipboard().clear()
|
||||
|
||||
# Select All
|
||||
assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) is True
|
||||
@@ -452,7 +452,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
||||
assert newPara[5] == ipsumText[4]
|
||||
assert newPara[6] == ipsumText[2]
|
||||
|
||||
qApp.clipboard().clear()
|
||||
QApplication.clipboard().clear()
|
||||
|
||||
# Emphasis/Undo/Redo
|
||||
# ==================
|
||||
@@ -1413,7 +1413,7 @@ def testGuiEditor_MultiBlockFormatting(qtbot, nwGUI, projPath, ipsumText, mockRn
|
||||
# Toggle Comment
|
||||
cursor = nwGUI.docEditor.textCursor()
|
||||
cursor.setPosition(50)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, 2000)
|
||||
cursor.movePosition(QtMoveRight, QtKeepAnchor, 2000)
|
||||
nwGUI.docEditor.setTextCursor(cursor)
|
||||
|
||||
nwGUI.docEditor._iterFormatBlocks(nwDocAction.BLOCK_COM)
|
||||
@@ -1434,7 +1434,7 @@ def testGuiEditor_MultiBlockFormatting(qtbot, nwGUI, projPath, ipsumText, mockRn
|
||||
# Un-toggle all
|
||||
cursor = nwGUI.docEditor.textCursor()
|
||||
cursor.setPosition(50)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, 3000)
|
||||
cursor.movePosition(QtMoveRight, QtKeepAnchor, 3000)
|
||||
nwGUI.docEditor.setTextCursor(cursor)
|
||||
|
||||
nwGUI.docEditor._iterFormatBlocks(nwDocAction.BLOCK_COM)
|
||||
@@ -1445,7 +1445,7 @@ def testGuiEditor_MultiBlockFormatting(qtbot, nwGUI, projPath, ipsumText, mockRn
|
||||
# Toggle Ignore Text
|
||||
cursor = nwGUI.docEditor.textCursor()
|
||||
cursor.setPosition(50)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, 2000)
|
||||
cursor.movePosition(QtMoveRight, QtKeepAnchor, 2000)
|
||||
nwGUI.docEditor.setTextCursor(cursor)
|
||||
|
||||
nwGUI.docEditor._iterFormatBlocks(nwDocAction.BLOCK_IGN)
|
||||
@@ -1456,7 +1456,7 @@ def testGuiEditor_MultiBlockFormatting(qtbot, nwGUI, projPath, ipsumText, mockRn
|
||||
# Clear all paragraphs
|
||||
cursor = nwGUI.docEditor.textCursor()
|
||||
cursor.setPosition(50)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, 3000)
|
||||
cursor.movePosition(QtMoveRight, QtKeepAnchor, 3000)
|
||||
nwGUI.docEditor.setTextCursor(cursor)
|
||||
|
||||
nwGUI.docEditor._iterFormatBlocks(nwDocAction.BLOCK_TXT)
|
||||
@@ -1788,7 +1788,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
assert abs(docEditor.getCursorPosition() - 1299) < 3
|
||||
|
||||
# Find next by button
|
||||
qtbot.mouseClick(docSearch.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert abs(docEditor.getCursorPosition() - 1513) < 3
|
||||
|
||||
# Activate loop search
|
||||
@@ -1806,14 +1806,14 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
docEditor.setCursorPosition(15)
|
||||
|
||||
# Toggle search again with header button
|
||||
qtbot.mouseClick(docEditor.docHeader.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docEditor.docHeader.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
docSearch.setSearchText("")
|
||||
assert docSearch.isVisible() is True
|
||||
|
||||
# Search for non-existing
|
||||
docEditor.setCursorPosition(0)
|
||||
docSearch.setSearchText("abcdef")
|
||||
qtbot.mouseClick(docSearch.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert docEditor.getCursorPosition() < 3 # No result
|
||||
|
||||
# Enable RegEx search
|
||||
@@ -1824,19 +1824,19 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
# Set invalid RegEx
|
||||
docEditor.setCursorPosition(0)
|
||||
docSearch.setSearchText(r"\bSus[")
|
||||
qtbot.mouseClick(docSearch.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert docEditor.getCursorPosition() < 3 # No result
|
||||
|
||||
# Set dangerous RegEx (issue #1015)
|
||||
# If this doesn't get caught, the app will hang
|
||||
docEditor.setCursorPosition(0)
|
||||
docSearch.setSearchText(r".*")
|
||||
qtbot.mouseClick(docSearch.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert abs(docEditor.getCursorPosition() - 14) < 3
|
||||
|
||||
# Set valid RegEx
|
||||
docSearch.setSearchText(r"\bSus")
|
||||
qtbot.mouseClick(docSearch.searchButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.searchButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert abs(docEditor.getCursorPosition() - 223) < 3
|
||||
|
||||
# Find next and then prev
|
||||
@@ -1887,7 +1887,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
assert abs(docEditor.getCursorPosition() - 223) < 3
|
||||
|
||||
# Replace "sus" with "foo" via replace button
|
||||
qtbot.mouseClick(docSearch.replaceButton, Qt.LeftButton, delay=KEY_DELAY)
|
||||
qtbot.mouseClick(docSearch.replaceButton, QtMouseLeft, delay=KEY_DELAY)
|
||||
assert docEditor.getText()[220:228] == "foocipit"
|
||||
|
||||
# Revert last two replaces
|
||||
|
||||
@@ -24,14 +24,15 @@ import pytest
|
||||
|
||||
from mocked import causeException
|
||||
|
||||
from PyQt5.QtGui import QMouseEvent, QTextCursor
|
||||
from PyQt5.QtCore import QEvent, QPoint, Qt, QUrl
|
||||
from PyQt5.QtWidgets import QMenu, qApp, QAction
|
||||
from PyQt5.QtGui import QMouseEvent, QTextCursor
|
||||
from PyQt5.QtWidgets import QAction, QApplication, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.enum import nwDocAction
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
from novelwriter.gui.docviewer import GuiDocViewer
|
||||
from novelwriter.types import QtMouseLeft, QtModeNone
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -59,9 +60,9 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
assert nwGUI.projView.projTree.getSelectedHandle() is None
|
||||
|
||||
# Re-select via header click
|
||||
button = Qt.MouseButton.LeftButton
|
||||
modifier = Qt.KeyboardModifier.NoModifier
|
||||
event = QMouseEvent(QEvent.MouseButtonPress, QPoint(), button, button, modifier)
|
||||
button = QtMouseLeft
|
||||
modifier = QtModeNone
|
||||
event = QMouseEvent(QEvent.Type.MouseButtonPress, QPoint(), button, button, modifier)
|
||||
docViewer.docHeader.mousePressEvent(event)
|
||||
assert nwGUI.projView.projTree.getSelectedHandle() == "88243afbe5ed8"
|
||||
|
||||
@@ -77,7 +78,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
docViewer.setTextCursor(cursor)
|
||||
docViewer._makeSelection(QTextCursor.WordUnderCursor)
|
||||
|
||||
qClip = qApp.clipboard()
|
||||
qClip = QApplication.clipboard()
|
||||
qClip.clear()
|
||||
|
||||
# Cut
|
||||
@@ -146,7 +147,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
docViewer.setTextCursor(cursor)
|
||||
docViewer._makeSelection(QTextCursor.WordUnderCursor)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QMenu, "exec_", mockExec)
|
||||
mp.setattr(QMenu, "exec", mockExec)
|
||||
docViewer._openContextMenu(docViewer.cursorRect().center())
|
||||
assert menuOpened
|
||||
|
||||
@@ -164,7 +165,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
assert docViewer.docHandle == "88243afbe5ed8"
|
||||
qtbot.mouseClick(docViewer.viewport(), Qt.ForwardButton, pos=rect.center(), delay=100)
|
||||
assert docViewer.docHandle == "4c4f28287af27"
|
||||
qtbot.mouseClick(docViewer.viewport(), Qt.LeftButton, pos=rect.center(), delay=100)
|
||||
qtbot.mouseClick(docViewer.viewport(), QtMouseLeft, pos=rect.center(), delay=100)
|
||||
assert docViewer.docHandle == "4c4f28287af27"
|
||||
|
||||
# Scroll bar default on empty document
|
||||
|
||||
@@ -60,7 +60,7 @@ def testGuiMain_ProjectBlocker(nwGUI):
|
||||
@pytest.mark.gui
|
||||
def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, projPath):
|
||||
"""Test the handling of launch tasks."""
|
||||
monkeypatch.setattr(GuiWelcome, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiWelcome, "exec", lambda *a: None)
|
||||
CONFIG.lastNotes = "0x0"
|
||||
buildTestProject(nwGUI, projPath)
|
||||
|
||||
@@ -511,7 +511,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
assert "test" in suggest
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QMenu, "exec_", lambda *a: None)
|
||||
mp.setattr(QMenu, "exec", lambda *a: None)
|
||||
docEditor.setCursorPosition(errPos)
|
||||
docEditor._openContextFromCursor()
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@ from __future__ import annotations
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from tools import buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QDialog, qApp, QMessageBox
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.dialogs.about import GuiAbout
|
||||
@@ -49,18 +47,18 @@ LANG_DATA = CONFIG.listLanguages(CONFIG.LANG_NW)
|
||||
@pytest.mark.parametrize("language", [a for a, b in LANG_DATA])
|
||||
def testGuiI18n_Localisation(qtbot, monkeypatch, language, nwGUI, projPath):
|
||||
"""Test loading the gui with a specific language."""
|
||||
monkeypatch.setattr(QDialog, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QDialog, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMessageBox, "result", lambda *a: QMessageBox.Yes)
|
||||
|
||||
# Set the test language
|
||||
CONFIG.guiLocale = language
|
||||
CONFIG.initLocalisation(qApp)
|
||||
CONFIG.initLocalisation(QApplication.instance()) # type: ignore
|
||||
|
||||
buildTestProject(nwGUI, projPath)
|
||||
nwGUI.show()
|
||||
|
||||
def showDialog(func: Callable, dType: QDialog) -> None:
|
||||
def showDialog(func, dType) -> None:
|
||||
func()
|
||||
qtbot.waitUntil(lambda: SHARED.findTopLevelWidget(dType) is not None, timeout=1000)
|
||||
dialog = SHARED.findTopLevelWidget(dType)
|
||||
|
||||
@@ -25,13 +25,13 @@ import pytest
|
||||
from tools import C, writeFile, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QTextCursor, QTextBlock
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert
|
||||
from novelwriter.constants import nwKeyWords, nwUnicode
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -359,7 +359,7 @@ def testGuiMenu_ContextMenus(qtbot, nwGUI, prjLipsum):
|
||||
rect = nwGUI.docEditor.cursorRect()
|
||||
|
||||
nwGUI.docEditor._openContextMenu(rect.bottomRight())
|
||||
qtbot.mouseClick(nwGUI.docEditor, Qt.LeftButton, pos=rect.topLeft())
|
||||
qtbot.mouseClick(nwGUI.docEditor, QtMouseLeft, pos=rect.topLeft())
|
||||
|
||||
nwGUI.docEditor._makePosSelection(QTextCursor.WordUnderCursor, rect.center())
|
||||
cursor = nwGUI.docEditor.textCursor()
|
||||
@@ -386,7 +386,7 @@ def testGuiMenu_ContextMenus(qtbot, nwGUI, prjLipsum):
|
||||
rect = nwGUI.docViewer.cursorRect()
|
||||
|
||||
nwGUI.docViewer._openContextMenu(rect.bottomRight())
|
||||
qtbot.mouseClick(nwGUI.docViewer, Qt.LeftButton, pos=rect.topLeft())
|
||||
qtbot.mouseClick(nwGUI.docViewer, QtMouseLeft, pos=rect.topLeft())
|
||||
|
||||
nwGUI.docViewer._makePosSelection(QTextCursor.WordUnderCursor, rect.center())
|
||||
cursor = nwGUI.docViewer.textCursor()
|
||||
@@ -410,12 +410,12 @@ def testGuiMenu_ContextMenus(qtbot, nwGUI, prjLipsum):
|
||||
assert nwGUI.docViewer.docHeader.backButton.isEnabled()
|
||||
assert not nwGUI.docViewer.docHeader.forwardButton.isEnabled()
|
||||
|
||||
qtbot.mouseClick(nwGUI.docViewer.docHeader.backButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(nwGUI.docViewer.docHeader.backButton, QtMouseLeft)
|
||||
assert nwGUI.docViewer.docHandle == "4c4f28287af27"
|
||||
assert not nwGUI.docViewer.docHeader.backButton.isEnabled()
|
||||
assert nwGUI.docViewer.docHeader.forwardButton.isEnabled()
|
||||
|
||||
qtbot.mouseClick(nwGUI.docViewer.docHeader.forwardButton, Qt.LeftButton)
|
||||
qtbot.mouseClick(nwGUI.docViewer.docHeader.forwardButton, QtMouseLeft)
|
||||
assert nwGUI.docViewer.docHandle == "04468803b92e1"
|
||||
assert nwGUI.docViewer.docHeader.backButton.isEnabled()
|
||||
assert not nwGUI.docViewer.docHeader.forwardButton.isEnabled()
|
||||
|
||||
@@ -26,14 +26,15 @@ from pathlib import Path
|
||||
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QFocusEvent
|
||||
from PyQt5.QtCore import QPoint, Qt, QEvent
|
||||
from PyQt5.QtGui import QFocusEvent
|
||||
from PyQt5.QtWidgets import QInputDialog, QToolTip
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwWidget, nwItemType
|
||||
from novelwriter.gui.noveltree import GuiNovelTree, NovelTreeColumn
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -112,7 +113,7 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
# Clear selection with mouse
|
||||
vPort = novelTree.viewport()
|
||||
qtbot.mouseClick(vPort, Qt.LeftButton, pos=vPort.rect().center(), delay=10)
|
||||
qtbot.mouseClick(vPort, QtMouseLeft, pos=vPort.rect().center(), delay=10)
|
||||
assert not scItem.isSelected()
|
||||
|
||||
# Double-click item
|
||||
@@ -224,7 +225,7 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
scItem = novelTree.topLevelItem(2)
|
||||
scItem.setSelected(True)
|
||||
assert scItem.isSelected()
|
||||
novelTree.focusOutEvent(QFocusEvent(QEvent.None_, Qt.MouseFocusReason))
|
||||
novelTree.focusOutEvent(QFocusEvent(QEvent.Type.None_, Qt.MouseFocusReason))
|
||||
assert not scItem.isSelected()
|
||||
|
||||
# Close
|
||||
|
||||
@@ -23,23 +23,24 @@ from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
from novelwriter.core.project import NWProject
|
||||
|
||||
from tools import C, buildTestProject
|
||||
from mocked import causeOSError
|
||||
from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QMouseEvent
|
||||
from PyQt5.QtCore import QEvent, QMimeData, QPoint, QTimer, Qt
|
||||
from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QMouseEvent
|
||||
from PyQt5.QtWidgets import QMessageBox, QMenu, QTreeWidget, QTreeWidgetItem, QDialog
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.enum import nwItemLayout, nwItemType, nwItemClass, nwWidget
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView, _TreeContextMenu
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.dialogs.docmerge import GuiDocMerge
|
||||
from novelwriter.dialogs.docsplit import GuiDocSplit
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwItemLayout, nwItemType, nwItemClass, nwWidget
|
||||
from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView, _TreeContextMenu
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.types import QtMouseLeft, QtMouseMiddle, QtModeNone
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -539,8 +540,8 @@ def testGuiProjTree_MergeDocuments(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
||||
mergeData = {}
|
||||
|
||||
monkeypatch.setattr(GuiDocMerge, "__init__", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocMerge, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocMerge, "result", lambda *a: QDialog.Accepted)
|
||||
monkeypatch.setattr(GuiDocMerge, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocMerge, "result", lambda *a: QDialog.DialogCode.Accepted)
|
||||
monkeypatch.setattr(GuiDocMerge, "getData", lambda *a: mergeData)
|
||||
|
||||
buildTestProject(nwGUI, projPath)
|
||||
@@ -596,7 +597,7 @@ def testGuiProjTree_MergeDocuments(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
||||
|
||||
# User cancels merge
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiDocMerge, "result", lambda *a: QDialog.Rejected)
|
||||
mp.setattr(GuiDocMerge, "result", lambda *a: QDialog.DialogCode.Rejected)
|
||||
assert projTree._mergeDocuments(hChapter1, True) is False
|
||||
|
||||
# The merge goes through
|
||||
@@ -640,8 +641,8 @@ def testGuiProjTree_SplitDocument(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
||||
splitText = []
|
||||
|
||||
monkeypatch.setattr(GuiDocSplit, "__init__", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocSplit, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocSplit, "result", lambda *a: QDialog.Accepted)
|
||||
monkeypatch.setattr(GuiDocSplit, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(GuiDocSplit, "result", lambda *a: QDialog.DialogCode.Accepted)
|
||||
monkeypatch.setattr(GuiDocSplit, "getData", lambda *a: (splitData, splitText))
|
||||
|
||||
# Create a project
|
||||
@@ -735,7 +736,7 @@ def testGuiProjTree_SplitDocument(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
||||
|
||||
# Cancelled by user
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiDocSplit, "result", lambda *a: QDialog.Rejected)
|
||||
mp.setattr(GuiDocSplit, "result", lambda *a: QDialog.DialogCode.Rejected)
|
||||
assert projTree._splitDocument(hSplitDoc) is False
|
||||
|
||||
# qtbot.stop()
|
||||
@@ -821,8 +822,8 @@ def testGuiProjTree_AutoScroll(qtbot, monkeypatch, nwGUI: GuiMain, projPath, moc
|
||||
|
||||
action = Qt.DropAction.MoveAction
|
||||
mime = QMimeData()
|
||||
mouse = Qt.MouseButton.LeftButton
|
||||
modifier = Qt.KeyboardModifier.NoModifier
|
||||
mouse = QtMouseLeft
|
||||
modifier = QtModeNone
|
||||
|
||||
# Scroll Down
|
||||
h = projTree.height()
|
||||
@@ -880,8 +881,8 @@ def testGuiProjTree_DragAndDrop(qtbot, monkeypatch, caplog, nwGUI: GuiMain, proj
|
||||
nPos = projTree.visualItemRect(projTree._getTreeItem(C.hNovelRoot)).bottomLeft()
|
||||
action = Qt.DropAction.MoveAction
|
||||
mime = QMimeData()
|
||||
mouse = Qt.MouseButton.LeftButton
|
||||
modifier = Qt.KeyboardModifier.NoModifier
|
||||
mouse = QtMouseLeft
|
||||
modifier = QtModeNone
|
||||
|
||||
projTree.saveTreeOrder()
|
||||
treeOrder = SHARED.project.tree._order
|
||||
@@ -1082,8 +1083,8 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
|
||||
|
||||
eType = QEvent.Type.MouseButtonPress
|
||||
pos = projTree.visualItemRect(projTree._getTreeItem(C.hChapterDoc)).center()
|
||||
button = Qt.MouseButton.MiddleButton
|
||||
modifier = Qt.KeyboardModifier.NoModifier
|
||||
button = QtMouseMiddle
|
||||
modifier = QtModeNone
|
||||
|
||||
# Trigger the viewer
|
||||
event = QMouseEvent(eType, pos, button, button, modifier)
|
||||
@@ -1092,7 +1093,7 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
|
||||
|
||||
# Trigger the left click clear
|
||||
pos = QPoint(5000, 5000)
|
||||
button = Qt.MouseButton.LeftButton
|
||||
button = QtMouseLeft
|
||||
event = QMouseEvent(eType, pos, button, button, modifier)
|
||||
projTree.setSelectedHandle(C.hChapterDoc)
|
||||
projTree.mousePressEvent(event)
|
||||
@@ -1162,7 +1163,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
# Pop the menu
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QMenu, "exec_", lambda *a: None)
|
||||
mp.setattr(QMenu, "exec", lambda *a: None)
|
||||
projTree.clearSelection()
|
||||
|
||||
# No item under menu
|
||||
|
||||
@@ -106,22 +106,22 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths):
|
||||
assert mainTheme._parseColour(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255)
|
||||
|
||||
# The palette should load with the parsed values
|
||||
mainTheme._setPalette(parser, "Palette", "colour1", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (100, 150, 200, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour2", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour3", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour4", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (250, 250, 0, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour5", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 0, 0, 0)
|
||||
mainTheme._setPalette(parser, "Palette", "colour6", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 127, 255, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour1", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour2", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour3", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour4", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (250, 250, 0, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour5", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 0)
|
||||
mainTheme._setPalette(parser, "Palette", "colour6", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 127, 255, 255)
|
||||
|
||||
# Non-existing value should return default colour
|
||||
mainTheme._setPalette(parser, "Palette", "stuff", QPalette.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 0, 0, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "stuff", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 255)
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
@@ -168,15 +168,15 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI):
|
||||
# ==================
|
||||
|
||||
# Set a mock colour for the window background
|
||||
mainTheme._guiPalette.color(QPalette.Window).setRgb(0, 0, 0, 0)
|
||||
mainTheme._guiPalette.color(QPalette.ColorRole.Window).setRgb(0, 0, 0, 0)
|
||||
|
||||
# Load the default theme
|
||||
CONFIG.guiTheme = "default"
|
||||
assert mainTheme.loadTheme() is True
|
||||
|
||||
# This should load a standard palette
|
||||
wCol = QApplication.style().standardPalette().color(QPalette.Window).getRgb()
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == wCol
|
||||
wCol = QApplication.style().standardPalette().color(QPalette.ColorRole.Window).getRgb()
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == wCol
|
||||
|
||||
# Load Default Light Theme
|
||||
# ========================
|
||||
@@ -185,10 +185,14 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI):
|
||||
assert mainTheme.loadTheme() is True
|
||||
|
||||
# Check a few values
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (239, 239, 239, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.WindowText).getRgb() == (0, 0, 0, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.Base).getRgb() == (255, 255, 255, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.AlternateBase).getRgb() == (239, 239, 239, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.Window).getRgb() == (239, 239, 239, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.WindowText).getRgb() == (0, 0, 0, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.Base).getRgb() == (255, 255, 255, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.AlternateBase).getRgb() == (239, 239, 239, 255)
|
||||
|
||||
# Load Default Dark Theme
|
||||
# =======================
|
||||
@@ -197,10 +201,14 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI):
|
||||
assert mainTheme.loadTheme() is True
|
||||
|
||||
# Check a few values
|
||||
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (54, 54, 54, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.WindowText).getRgb() == (204, 204, 204, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.Base).getRgb() == (62, 62, 62, 255)
|
||||
assert mainTheme._guiPalette.color(QPalette.AlternateBase).getRgb() == (78, 78, 78, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.Window).getRgb() == (54, 54, 54, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.WindowText).getRgb() == (204, 204, 204, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.Base).getRgb() == (62, 62, 62, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
QPalette.ColorRole.AlternateBase).getRgb() == (78, 78, 78, 255)
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ def testToolLipsum_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
assert nwGUI.openDocument(C.hSceneDoc) is True
|
||||
nwGUI.docEditor.setCursorLine(3)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiLipsum, "exec_", lambda *a: None)
|
||||
mp.setattr(GuiLipsum, "exec", lambda *a: None)
|
||||
mp.setattr(GuiLipsum, "lipsumText", "FooBar")
|
||||
nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger)
|
||||
assert nwGUI.docEditor.getText() == "### New Scene\n\nFooBar"
|
||||
|
||||
@@ -27,15 +27,16 @@ from pytestqt.qtbot import QtBot
|
||||
|
||||
from tools import buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtWidgets import QDialogButtonBox, QFileDialog, QListWidgetItem, QMessageBox
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtWidgets import QFileDialog, QListWidgetItem, QMessageBox
|
||||
|
||||
from novelwriter.constants import nwLabels
|
||||
from novelwriter.core.buildsettings import BuildSettings
|
||||
from novelwriter.enum import nwBuildFmt
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.constants import nwLabels
|
||||
from novelwriter.tools.manusbuild import GuiManuscriptBuild
|
||||
from novelwriter.core.buildsettings import BuildSettings
|
||||
from novelwriter.types import QtDialogClose
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -94,7 +95,7 @@ def testManuscriptBuild_Main(
|
||||
assert (fncPath / "TestBuild").with_suffix(nwLabels.BUILD_EXT[fmt]).exists()
|
||||
lastFmt = fmt
|
||||
|
||||
manus._dialogButtonClicked(manus.dlgButtons.button(QDialogButtonBox.Close))
|
||||
manus._dialogButtonClicked(manus.dlgButtons.button(QtDialogClose))
|
||||
manus.deleteLater()
|
||||
|
||||
assert build.lastBuildName == "TestBuild"
|
||||
@@ -149,7 +150,7 @@ def testManuscriptBuild_Main(
|
||||
assert lastUrl.startswith("file://")
|
||||
|
||||
# Finish
|
||||
manus._dialogButtonClicked(manus.dlgButtons.button(QDialogButtonBox.Close))
|
||||
manus._dialogButtonClicked(manus.dlgButtons.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testManuscriptBuild_Main
|
||||
|
||||
@@ -31,7 +31,7 @@ from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtPrintSupport import QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import QAction, QDialogButtonBox, QListWidgetItem
|
||||
from PyQt5.QtWidgets import QAction, QListWidgetItem
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwHeadFmt
|
||||
@@ -40,7 +40,7 @@ from novelwriter.guimain import GuiMain
|
||||
from novelwriter.tools.manusbuild import GuiManuscriptBuild
|
||||
from novelwriter.tools.manuscript import GuiManuscript
|
||||
from novelwriter.tools.manussettings import GuiBuildSettings
|
||||
from novelwriter.types import QtAlignAbsolute, QtAlignJustify
|
||||
from novelwriter.types import QtAlignAbsolute, QtAlignJustify, QtDialogApply, QtDialogSave
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -118,7 +118,7 @@ def testManuscript_Builds(qtbot: QtBot, nwGUI: GuiMain, projPath: Path):
|
||||
|
||||
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
|
||||
bSettings.newSettingsReady.connect(_testNewSettingsReady)
|
||||
bSettings.buttonBox.button(QDialogButtonBox.Save).click()
|
||||
bSettings.buttonBox.button(QtDialogSave).click()
|
||||
|
||||
assert isinstance(build, BuildSettings)
|
||||
assert build.name == "Test Build"
|
||||
@@ -135,7 +135,7 @@ def testManuscript_Builds(qtbot: QtBot, nwGUI: GuiMain, projPath: Path):
|
||||
|
||||
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
|
||||
bSettings.newSettingsReady.connect(_testNewSettingsReady)
|
||||
bSettings.buttonBox.button(QDialogButtonBox.Apply).click() # Should leave the dialog open
|
||||
bSettings.buttonBox.button(QtDialogApply).click() # Should leave the dialog open
|
||||
|
||||
assert isinstance(build, BuildSettings)
|
||||
assert build.name == "Test Build"
|
||||
@@ -278,7 +278,7 @@ def testManuscript_Features(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
build._changed = True
|
||||
manus.buildList.clearSelection()
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("novelwriter.tools.manusbuild.GuiManuscriptBuild.exec_", lambda *a: None)
|
||||
mp.setattr("novelwriter.tools.manusbuild.GuiManuscriptBuild.exec", lambda *a: None)
|
||||
|
||||
manus.buildList.setCurrentRow(0)
|
||||
manus.btnBuild.click()
|
||||
@@ -313,7 +313,7 @@ def testManuscript_Print(monkeypatch, qtbot: QtBot, nwGUI: GuiMain, projPath: Pa
|
||||
assert manus.docPreview.toPlainText().strip() != ""
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(QPrintPreviewDialog, "exec_", lambda *a: None)
|
||||
mp.setattr(QPrintPreviewDialog, "exec", lambda *a: None)
|
||||
manus.btnPrint.click()
|
||||
for obj in manus.children():
|
||||
if isinstance(obj, QPrintPreviewDialog):
|
||||
|
||||
@@ -29,7 +29,7 @@ from tools import C, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QFont
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtWidgets import QDialogButtonBox, QFontDialog
|
||||
from PyQt5.QtWidgets import QFontDialog
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -38,6 +38,7 @@ from novelwriter.core.buildsettings import BuildSettings, FilterMode
|
||||
from novelwriter.tools.manussettings import (
|
||||
GuiBuildSettings, _OutputTab, _FormatTab, _ContentTab, _HeadingsTab, _FilterTab
|
||||
)
|
||||
from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -80,7 +81,7 @@ def testBuildSettings_Init(qtbot: QtBot, nwGUI: GuiMain, projPath: Path, mockRnd
|
||||
# Capture Apply button
|
||||
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
|
||||
bSettings.newSettingsReady.connect(_testNewSettingsReady)
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Apply))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogApply))
|
||||
|
||||
assert triggered
|
||||
|
||||
@@ -89,7 +90,7 @@ def testBuildSettings_Init(qtbot: QtBot, nwGUI: GuiMain, projPath: Path, mockRnd
|
||||
|
||||
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
|
||||
bSettings.newSettingsReady.connect(_testNewSettingsReady)
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Save))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogSave))
|
||||
|
||||
assert triggered
|
||||
|
||||
@@ -106,7 +107,7 @@ def testBuildSettings_Init(qtbot: QtBot, nwGUI: GuiMain, projPath: Path, mockRnd
|
||||
assert triggered
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Init
|
||||
@@ -312,7 +313,7 @@ def testBuildSettings_Filter(qtbot: QtBot, nwGUI: GuiMain, projPath: Path, mockR
|
||||
]
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Filter
|
||||
@@ -484,7 +485,7 @@ def testBuildSettings_Headings(qtbot: QtBot, nwGUI: GuiMain):
|
||||
assert build.getBool("headings.hideSection") is True
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Headings
|
||||
@@ -546,7 +547,7 @@ def testBuildSettings_Content(qtbot: QtBot, nwGUI: GuiMain):
|
||||
assert build.getBool("text.addNoteHeadings") is True
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Content
|
||||
@@ -648,7 +649,7 @@ def testBuildSettings_Format(monkeypatch, qtbot: QtBot, nwGUI: GuiMain):
|
||||
assert fmtTab.textSize.value() == 10
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Format
|
||||
@@ -707,7 +708,7 @@ def testBuildSettings_Output(qtbot: QtBot, nwGUI: GuiMain):
|
||||
assert outTab.odtPageHeader.text() == nwHeadFmt.ODT_AUTO
|
||||
|
||||
# Finish
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QDialogButtonBox.Close))
|
||||
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testBuildSettings_Output
|
||||
|
||||
@@ -26,13 +26,14 @@ from pathlib import Path
|
||||
from datetime import datetime
|
||||
from pytestqt.qtbot import QtBot
|
||||
|
||||
from PyQt5.QtCore import QPoint, Qt
|
||||
from PyQt5.QtCore import QPoint
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.enum import nwItemClass
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.tools.welcome import GuiWelcome
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -70,7 +71,7 @@ def testToolWelcome_Main(qtbot: QtBot, monkeypatch, nwGUI, fncPath):
|
||||
@pytest.mark.gui
|
||||
def testToolWelcome_Open(qtbot: QtBot, monkeypatch, nwGUI, fncPath):
|
||||
"""Test the open tab in the Welcome window."""
|
||||
monkeypatch.setattr(QMenu, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(QMenu, "exec", lambda *a: None)
|
||||
monkeypatch.setattr(QMenu, "deleteLater", lambda *a: None)
|
||||
|
||||
CONFIG.recentProjects.update("/stuff/project_one", "Project One", 12345, 1690000000)
|
||||
@@ -100,19 +101,19 @@ def testToolWelcome_Open(qtbot: QtBot, monkeypatch, nwGUI, fncPath):
|
||||
|
||||
# Single click item
|
||||
assert tabOpen.selectedPath.text() == "Path: /stuff/project_two"
|
||||
qtbot.mouseClick(vPort, Qt.MouseButton.LeftButton, pos=posTwo, delay=10)
|
||||
qtbot.mouseClick(vPort, QtMouseLeft, pos=posTwo, delay=10)
|
||||
assert tabOpen.selectedPath.text() == "Path: /stuff/project_one"
|
||||
|
||||
# Double click item
|
||||
qtbot.mouseClick(vPort, Qt.MouseButton.LeftButton, pos=posTwo, delay=10)
|
||||
qtbot.mouseClick(vPort, QtMouseLeft, pos=posTwo, delay=10)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(welcome, "close", lambda *a: None)
|
||||
with qtbot.waitSignal(welcome.openProjectRequest, timeout=5000) as signal:
|
||||
qtbot.mouseDClick(vPort, Qt.MouseButton.LeftButton, pos=posTwo, delay=10)
|
||||
qtbot.mouseDClick(vPort, QtMouseLeft, pos=posTwo, delay=10)
|
||||
assert signal.args and signal.args[0] == Path("/stuff/project_one")
|
||||
|
||||
# Press open button
|
||||
qtbot.mouseClick(vPort, Qt.MouseButton.LeftButton, pos=posTwo, delay=10)
|
||||
qtbot.mouseClick(vPort, QtMouseLeft, pos=posTwo, delay=10)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(welcome, "close", lambda *a: None)
|
||||
with qtbot.waitSignal(welcome.openProjectRequest, timeout=5000) as signal:
|
||||
@@ -128,7 +129,7 @@ def testToolWelcome_Open(qtbot: QtBot, monkeypatch, nwGUI, fncPath):
|
||||
return obj
|
||||
return None
|
||||
|
||||
qtbot.mouseClick(vPort, Qt.MouseButton.LeftButton, pos=posOne, delay=10)
|
||||
qtbot.mouseClick(vPort, QtMouseLeft, pos=posOne, delay=10)
|
||||
ctxMenu = getMenuForPos(posOne)
|
||||
assert isinstance(ctxMenu, QMenu)
|
||||
assert ctxMenu.actions()[0].text() == "Open Project"
|
||||
|
||||
@@ -25,15 +25,15 @@ import pytest
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from tools import buildTestProject
|
||||
from mocked import causeOSError
|
||||
from tools import buildTestProject
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog
|
||||
|
||||
from novelwriter import SHARED
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.tools.writingstats import GuiWritingStats
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@@ -97,11 +97,11 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda *a, **k: ("", ""))
|
||||
assert not sessLog._saveData(sessLog.FMT_CSV)
|
||||
assert not sessLog._saveData(sessLog.FMT_JSON)
|
||||
assert not sessLog._saveData(None)
|
||||
assert not sessLog._saveData(None) # type: ignore
|
||||
|
||||
# Make the save succeed
|
||||
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda ss, tt, pp, options: (pp, ""))
|
||||
sessLog.listBox.sortByColumn(sessLog.C_TIME, 0)
|
||||
sessLog.listBox.sortByColumn(sessLog.C_TIME, 0) # type: ignore
|
||||
|
||||
assert sessLog.novelWords.text() == "{:n}".format(600)
|
||||
assert sessLog.notesWords.text() == "{:n}".format(275)
|
||||
@@ -156,7 +156,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
# ============
|
||||
|
||||
# No Novel Files
|
||||
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.incNovel, QtMouseLeft)
|
||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||
|
||||
jsonStats = tstPaths.tmpDir / "sessionStats.json"
|
||||
@@ -201,8 +201,8 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
]
|
||||
|
||||
# No Note Files
|
||||
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.incNovel, QtMouseLeft)
|
||||
qtbot.mouseClick(sessLog.incNotes, QtMouseLeft)
|
||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||
|
||||
jsonStats = tstPaths.tmpDir / "sessionStats.json"
|
||||
@@ -247,8 +247,8 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
]
|
||||
|
||||
# No Negative Entries
|
||||
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.incNotes, QtMouseLeft)
|
||||
qtbot.mouseClick(sessLog.hideNegative, QtMouseLeft)
|
||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||
|
||||
# qtbot.stop()
|
||||
@@ -279,8 +279,8 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
]
|
||||
|
||||
# Un-hide Zero Entries
|
||||
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.hideZeros, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.hideNegative, QtMouseLeft)
|
||||
qtbot.mouseClick(sessLog.hideZeros, QtMouseLeft)
|
||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||
|
||||
jsonStats = tstPaths.tmpDir / "sessionStats.json"
|
||||
@@ -333,7 +333,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
|
||||
]
|
||||
|
||||
# Group by Day
|
||||
qtbot.mouseClick(sessLog.groupByDay, Qt.LeftButton)
|
||||
qtbot.mouseClick(sessLog.groupByDay, QtMouseLeft)
|
||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||
|
||||
jsonStats = tstPaths.tmpDir / "sessionStats.json"
|
||||
|
||||
Reference in New Issue
Block a user