Skip to content

Commit

Permalink
Clean up alert boxes and update event filters (#1631)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Nov 29, 2023
2 parents 1edfcfc + 1118f01 commit ef93b41
Show file tree
Hide file tree
Showing 19 changed files with 116 additions and 156 deletions.
13 changes: 0 additions & 13 deletions novelwriter/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QCoreApplication, QUrl
from PyQt5.QtWidgets import QWidget, qApp

from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
from novelwriter.error import logException
Expand Down Expand Up @@ -508,18 +507,6 @@ def openExternalPath(path: Path) -> bool:
return False


# =============================================================================================== #
# Other Functions
# =============================================================================================== #

def getGuiItem(objName: str) -> QWidget | None:
"""Returns a QtWidget based on its objectName."""
for qWidget in qApp.topLevelWidgets():
if qWidget.objectName() == objName:
return qWidget
return None


# =============================================================================================== #
# Classes
# =============================================================================================== #
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/core/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def __init__(self) -> None:

return

def __del__(self): # pragma: no cover
def __del__(self) -> None: # pragma: no cover
logger.debug("Delete: NWProject")
return

Expand Down
2 changes: 1 addition & 1 deletion novelwriter/core/spellcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __init__(self, project: NWProject) -> None:
logger.debug("Ready: NWSpellEnchant")
return

def __del__(self): # pragma: no cover
def __del__(self) -> None: # pragma: no cover
logger.debug("Delete: NWSpellEnchant")
return

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""
novelWriter – Custom Object: Wheel Event Filter
===============================================
novelWriter – Custom Objects: Event Filters
===========================================
File History:
Created: 2023-08-31 [2.1rc1]
Created: 2023-08-31 [2.1rc1] WheelEventFilter
Created: 2023-11-28 [2.2] StatusTipFilter
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Expand All @@ -23,7 +24,7 @@
"""
from __future__ import annotations

from PyQt5.QtGui import QWheelEvent
from PyQt5.QtGui import QStatusTipEvent, QWheelEvent
from PyQt5.QtCore import QEvent, QObject
from PyQt5.QtWidgets import QWidget

Expand Down Expand Up @@ -63,3 +64,12 @@ def eventFilter(self, object: QObject, event: QEvent) -> bool:
return False

# END Class WheelEventFilter


class StatusTipFilter(QObject):

def eventFilter(self, obj: QObject, event: QEvent) -> bool:
"""Filter out status tip events on menus."""
return True if isinstance(event, QStatusTipEvent) else super().eventFilter(obj, event)

# END Class StatusTipFilter
2 changes: 1 addition & 1 deletion novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
from novelwriter.core.document import NWDocument
from novelwriter.gui.dochighlight import GuiDocHighlighter
from novelwriter.gui.editordocument import GuiTextDocument
from novelwriter.extensions.wheeleventfilter import WheelEventFilter
from novelwriter.extensions.eventfilters import WheelEventFilter

if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/gui/docviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
from novelwriter.error import logException
from novelwriter.constants import nwUnicode
from novelwriter.core.tohtml import ToHtml
from novelwriter.extensions.wheeleventfilter import WheelEventFilter
from novelwriter.extensions.eventfilters import WheelEventFilter

if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/gui/editordocument.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, parent: QObject) -> None:

return

def __del__(self): # pragma: no cover
def __del__(self) -> None: # pragma: no cover
logger.debug("Delete: GuiTextDocument")
return

Expand Down
17 changes: 4 additions & 13 deletions novelwriter/gui/mainmenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
===========================
File History:
Created: 2019-04-27 [0.0.1] GuiMainMenu
Created: 2023-11-28 [2.2] StatusTipFilter
Created: 2019-04-27 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Expand All @@ -29,14 +28,15 @@
from typing import TYPE_CHECKING
from pathlib import Path

from PyQt5.QtGui import QDesktopServices, QStatusTipEvent
from PyQt5.QtCore import QEvent, QObject, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QMenuBar, QAction

from novelwriter import CONFIG, SHARED
from novelwriter.enum import nwDocAction, nwDocInsert, nwWidget
from novelwriter.common import openExternalPath
from novelwriter.constants import nwConst, trConst, nwKeyWords, nwLabels, nwUnicode
from novelwriter.extensions.eventfilters import StatusTipFilter

if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
Expand Down Expand Up @@ -971,12 +971,3 @@ def _buildHelpMenu(self) -> None:
return

# END Class GuiMainMenu


class StatusTipFilter(QObject):

def eventFilter(self, obj: QObject, event: QEvent) -> bool:
"""Filter out status tip events."""
return True if isinstance(event, QStatusTipEvent) else super().eventFilter(obj, event)

# END Class StatusTipFilter
2 changes: 1 addition & 1 deletion novelwriter/gui/projtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@ def __init__(self, projTree: GuiProjectTree, nwItem: NWItem) -> None:

return

def __del__(self): # pragma: no cover
def __del__(self) -> None: # pragma: no cover
logger.debug("Delete: _TreeContextMenu")
return

Expand Down
6 changes: 4 additions & 2 deletions novelwriter/gui/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

from typing import TYPE_CHECKING

from PyQt5.QtCore import QEvent, QPoint, Qt, QSize, pyqtSignal
from PyQt5.QtGui import QPalette
from PyQt5.QtCore import QEvent, QPoint, Qt, QSize, pyqtSignal
from PyQt5.QtWidgets import QMenu, QToolButton, QVBoxLayout, QWidget

from novelwriter import CONFIG, SHARED
from novelwriter.enum import nwView
from novelwriter.extensions.eventfilters import StatusTipFilter

if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain
Expand All @@ -54,6 +55,7 @@ def __init__(self, mainGui: GuiMain) -> None:
iPx = CONFIG.pxInt(24)
iconSize = QSize(iPx, iPx)
self.setContentsMargins(0, 0, 0, 0)
self.installEventFilter(StatusTipFilter(mainGui))

# Buttons
self.tbProject = QToolButton(self)
Expand Down Expand Up @@ -162,7 +164,7 @@ def updateTheme(self) -> None:

class _PopRightMenu(QMenu):

def event(self, event: QEvent):
def event(self, event: QEvent) -> bool:
"""Overload the show event and move the menu popup location."""
if event.type() == QEvent.Show:
parent = self.parent()
Expand Down
66 changes: 40 additions & 26 deletions novelwriter/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
class SharedData(QObject):

__slots__ = (
"_gui", "_theme", "_project", "_spelling", "_lockedBy", "_alert",
"_gui", "_theme", "_project", "_spelling", "_lockedBy", "_lastAlert",
"_idleTime", "_idleRefTime",
)

Expand All @@ -68,7 +68,7 @@ def __init__(self) -> None:

# Settings
self._lockedBy = None
self._alert = None
self._lastAlert = ""
self._idleTime = 0.0
self._idleRefTime = time()

Expand Down Expand Up @@ -122,9 +122,9 @@ def projectIdleTime(self) -> float:
return self._idleTime

@property
def alert(self) -> _GuiAlert | None:
"""Return a pointer to the last alert box."""
return self._alert
def lastAlert(self) -> str:
"""Return the last alert message."""
return self._lastAlert

##
# Methods
Expand Down Expand Up @@ -238,44 +238,53 @@ def indexSignalProxy(self, data: dict) -> None:

def info(self, text: str, info: str = "", details: str = "", log: bool = True) -> None:
"""Open an information alert box."""
self._alert = _GuiAlert(self.mainGui, self.theme)
self._alert.setMessage(text, info, details)
self._alert.setAlertType(_GuiAlert.INFO, False)
alert = _GuiAlert(self.mainGui, self.theme)
alert.setMessage(text, info, details)
alert.setAlertType(_GuiAlert.INFO, False)
self._lastAlert = alert.logMessage
if log:
logger.info(self._alert.logMessage, stacklevel=2)
self._alert.exec_()
logger.info(self._lastAlert, stacklevel=2)
alert.exec_()
alert.deleteLater()
return

def warn(self, text: str, info: str = "", details: str = "", log: bool = True) -> None:
"""Open a warning alert box."""
self._alert = _GuiAlert(self.mainGui, self.theme)
self._alert.setMessage(text, info, details)
self._alert.setAlertType(_GuiAlert.WARN, False)
alert = _GuiAlert(self.mainGui, self.theme)
alert.setMessage(text, info, details)
alert.setAlertType(_GuiAlert.WARN, False)
self._lastAlert = alert.logMessage
if log:
logger.warning(self._alert.logMessage, stacklevel=2)
self._alert.exec_()
logger.warning(self._lastAlert, stacklevel=2)
alert.exec_()
alert.deleteLater()
return

def error(self, text: str, info: str = "", details: str = "", log: bool = True,
exc: Exception | None = None) -> None:
"""Open an error alert box."""
self._alert = _GuiAlert(self.mainGui, self.theme)
self._alert.setMessage(text, info, details)
self._alert.setAlertType(_GuiAlert.ERROR, False)
alert = _GuiAlert(self.mainGui, self.theme)
alert.setMessage(text, info, details)
alert.setAlertType(_GuiAlert.ERROR, False)
if exc:
self._alert.setException(exc)
alert.setException(exc)
self._lastAlert = alert.logMessage
if log:
logger.error(self._alert.logMessage, stacklevel=2)
self._alert.exec_()
logger.error(self._lastAlert, stacklevel=2)
alert.exec_()
alert.deleteLater()
return

def question(self, text: str, info: str = "", details: str = "", warn: bool = False) -> bool:
"""Open a question box."""
self._alert = _GuiAlert(self.mainGui, self.theme)
self._alert.setMessage(text, info, details)
self._alert.setAlertType(_GuiAlert.WARN if warn else _GuiAlert.ASK, True)
self._alert.exec_()
return self._alert.result() == QMessageBox.Yes
alert = _GuiAlert(self.mainGui, self.theme)
alert.setMessage(text, info, details)
alert.setAlertType(_GuiAlert.WARN if warn else _GuiAlert.ASK, True)
self._lastAlert = alert.logMessage
alert.exec_()
isYes = alert.result() == QMessageBox.StandardButton.Yes
alert.deleteLater()
return isYes

##
# Internal Functions
Expand Down Expand Up @@ -312,6 +321,11 @@ def __init__(self, parent: QWidget, theme: GuiTheme) -> None:
super().__init__(parent=parent)
self._theme = theme
self._message = ""
logger.debug("Ready: _GuiAlert")
return

def __del__(self) -> None: # pragma: no cover
logger.debug("Delete: _GuiAlert")
return

@property
Expand Down
Loading

0 comments on commit ef93b41

Please sign in to comment.