From 43cdc8420c56d937b8497a436017d42758393f0e Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sun, 16 Jun 2024 16:14:11 +0200
Subject: [PATCH 1/2] Merge progress bars into single source file
---
.../{circularprogress.py => progressbars.py} | 29 ++++++++--
novelwriter/extensions/simpleprogress.py | 53 -------------------
novelwriter/tools/manusbuild.py | 2 +-
novelwriter/tools/manuscript.py | 2 +-
4 files changed, 28 insertions(+), 58 deletions(-)
rename novelwriter/extensions/{circularprogress.py => progressbars.py} (79%)
delete mode 100644 novelwriter/extensions/simpleprogress.py
diff --git a/novelwriter/extensions/circularprogress.py b/novelwriter/extensions/progressbars.py
similarity index 79%
rename from novelwriter/extensions/circularprogress.py
rename to novelwriter/extensions/progressbars.py
index de360d827..60e2b3566 100644
--- a/novelwriter/extensions/circularprogress.py
+++ b/novelwriter/extensions/progressbars.py
@@ -1,9 +1,10 @@
"""
-novelWriter – Custom Widget: Progress Circle
-============================================
+novelWriter – Custom Widget: Progress Bars
+==========================================
File History:
-Created: 2023-06-07 [2.1b1]
+Created: 2023-06-07 [2.1b1] NProgressCircle
+Created: 2023-06-09 [2.1b1] NProgressSimple
This file is a part of novelWriter
Copyright 2018–2024, Veronica Berglyd Olsen
@@ -101,3 +102,25 @@ def paintEvent(self, event: QPaintEvent) -> None:
painter.setPen(self._tColor)
painter.drawText(self._cRect, QtAlignCenter, self._text or f"{progress:.1f} %")
return
+
+
+class NProgressSimple(QProgressBar):
+ """Extension: Simple Progress Widget
+
+ A custom widget that paints a plain bar with no other styling.
+ """
+
+ def __init__(self, parent: QWidget) -> None:
+ super().__init__(parent=parent)
+ return
+
+ def paintEvent(self, event: QPaintEvent) -> None:
+ """Custom painter for the progress bar."""
+ if (value := self.value()) > 0:
+ progress = ceil(self.width()*float(value)/self.maximum())
+ painter = QPainter(self)
+ painter.setRenderHint(QtPaintAnitAlias, True)
+ painter.setPen(self.palette().highlight().color())
+ painter.setBrush(self.palette().highlight())
+ painter.drawRect(0, 0, progress, self.height())
+ return
diff --git a/novelwriter/extensions/simpleprogress.py b/novelwriter/extensions/simpleprogress.py
deleted file mode 100644
index f940c73cb..000000000
--- a/novelwriter/extensions/simpleprogress.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-novelWriter – Custom Widget: Progress Simple
-============================================
-
-File History:
-Created: 2023-06-09 [2.1b1]
-
-This file is a part of novelWriter
-Copyright 2018–2024, Veronica Berglyd Olsen
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-"""
-from __future__ import annotations
-
-from math import ceil
-
-from PyQt5.QtGui import QPainter, QPaintEvent
-from PyQt5.QtWidgets import QProgressBar, QWidget
-
-from novelwriter.types import QtPaintAnitAlias
-
-
-class NProgressSimple(QProgressBar):
- """Extension: Simple Progress Widget
-
- A custom widget that paints a plain bar with no other styling.
- """
-
- def __init__(self, parent: QWidget) -> None:
- super().__init__(parent=parent)
- return
-
- def paintEvent(self, event: QPaintEvent) -> None:
- """Custom painter for the progress bar."""
- if (value := self.value()) > 0:
- progress = ceil(self.width()*float(value)/self.maximum())
- painter = QPainter(self)
- painter.setRenderHint(QtPaintAnitAlias, True)
- painter.setPen(self.palette().highlight().color())
- painter.setBrush(self.palette().highlight())
- painter.drawRect(0, 0, progress, self.height())
- return
diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py
index 90f6f2964..cf18822b8 100644
--- a/novelwriter/tools/manusbuild.py
+++ b/novelwriter/tools/manusbuild.py
@@ -43,7 +43,7 @@
from novelwriter.core.item import NWItem
from novelwriter.enum import nwBuildFmt
from novelwriter.extensions.modified import NDialog, NIconToolButton
-from novelwriter.extensions.simpleprogress import NProgressSimple
+from novelwriter.extensions.progressbars import NProgressSimple
from novelwriter.types import QtAlignCenter, QtDialogClose, QtRoleAction, QtRoleReject, QtUserRole
logger = logging.getLogger(__name__)
diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py
index 53f3a17b0..4c2167428 100644
--- a/novelwriter/tools/manuscript.py
+++ b/novelwriter/tools/manuscript.py
@@ -44,8 +44,8 @@
from novelwriter.core.docbuild import NWBuildDocument
from novelwriter.core.tokenizer import HeadingFormatter
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
-from novelwriter.extensions.circularprogress import NProgressCircle
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
+from novelwriter.extensions.progressbars import NProgressCircle
from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
from novelwriter.tools.manusbuild import GuiManuscriptBuild
from novelwriter.tools.manussettings import GuiBuildSettings
From 53522908c8f938a5a2c2ef48eeba2b0a608e5bbd Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sun, 16 Jun 2024 17:29:29 +0200
Subject: [PATCH 2/2] Improve test coverage
---
tests/test_ext/test_ext_progressbars.py | 78 +++++++++++++++++++++++++
tests/test_ext/test_ext_switch.py | 74 +++++++++++++++++++++++
tests/tools.py | 14 +++--
3 files changed, 161 insertions(+), 5 deletions(-)
create mode 100644 tests/test_ext/test_ext_progressbars.py
create mode 100644 tests/test_ext/test_ext_switch.py
diff --git a/tests/test_ext/test_ext_progressbars.py b/tests/test_ext/test_ext_progressbars.py
new file mode 100644
index 000000000..66477feb0
--- /dev/null
+++ b/tests/test_ext/test_ext_progressbars.py
@@ -0,0 +1,78 @@
+"""
+novelWriter – Progress Bar Tester
+=================================
+
+This file is a part of novelWriter
+Copyright 2018–2024, Veronica Berglyd Olsen
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from __future__ import annotations
+
+from time import sleep
+
+import pytest
+
+from PyQt5.QtGui import QColor
+
+from novelwriter.extensions.progressbars import NProgressCircle, NProgressSimple
+
+from tests.tools import SimpleDialog
+
+
+@pytest.mark.gui
+def testExtProgressBars_NProgressCircle(qtbot):
+ """Test the NProgressCircle class."""
+ dialog = SimpleDialog()
+ progress = NProgressCircle(dialog, 200, 16)
+
+ with qtbot.waitExposed(dialog):
+ # This ensures the paint event is executed
+ dialog.show()
+
+ dialog.resize(200, 200)
+ progress.setColours(
+ QColor(255, 255, 255), QColor(255, 192, 192),
+ QColor(255, 0, 0), QColor(0, 0, 0),
+ )
+
+ progress.setMaximum(100)
+ for i in range(1, 101):
+ progress.setValue(i)
+ sleep(0.0025)
+ assert progress.value() == i
+
+ progress.setCentreText("Done!")
+ assert progress._text == "Done!"
+
+ # qtbot.stop()
+
+
+@pytest.mark.gui
+def testExtProgressBars_NProgressSimple(qtbot):
+ """Test the NProgressSimple class."""
+ dialog = SimpleDialog()
+ progress = NProgressSimple(dialog)
+
+ with qtbot.waitExposed(dialog):
+ # This ensures the paint event is executed
+ dialog.show()
+
+ progress.setMaximum(100)
+ for i in range(1, 101):
+ progress.setValue(i)
+ sleep(0.0025)
+ assert progress.value() == i
+
+ # qtbot.stop()
diff --git a/tests/test_ext/test_ext_switch.py b/tests/test_ext/test_ext_switch.py
new file mode 100644
index 000000000..6268721e3
--- /dev/null
+++ b/tests/test_ext/test_ext_switch.py
@@ -0,0 +1,74 @@
+"""
+novelWriter – Switch Tester
+===========================
+
+This file is a part of novelWriter
+Copyright 2018–2024, Veronica Berglyd Olsen
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from __future__ import annotations
+
+import pytest
+
+from PyQt5.QtCore import QEvent, QPoint
+from PyQt5.QtGui import QMouseEvent
+
+from novelwriter.extensions.switch import NSwitch
+from novelwriter.types import QtModNone, QtMouseLeft
+
+from tests.tools import SimpleDialog
+
+
+@pytest.mark.gui
+def testExtSwitch_Main(qtbot):
+ """Test the NSwitch class. This is mostly a check that all the calls
+ work as the result is visual.
+ """
+ dialog = SimpleDialog()
+ switch = NSwitch(dialog, 40)
+
+ with qtbot.waitExposed(dialog):
+ # This ensures the paint event is executed
+ dialog.show()
+
+ dialog.resize(200, 100)
+
+ switch.setEnabled(False)
+ switch.setChecked(False)
+ switch.repaint()
+ qtbot.wait(20)
+
+ switch.setChecked(True)
+ switch.repaint()
+ qtbot.wait(20)
+
+ switch.setEnabled(True)
+ switch.setChecked(False)
+ switch.repaint()
+ qtbot.wait(20)
+
+ switch.setChecked(True)
+ switch.repaint()
+ qtbot.wait(20)
+
+ button = QtMouseLeft
+ modifier = QtModNone
+ event = QMouseEvent(QEvent.Type.MouseButtonRelease, QPoint(), button, button, modifier)
+ switch.mouseReleaseEvent(event)
+
+ event = QEvent(QEvent.Type.Enter)
+ switch.enterEvent(event)
+
+ # qtbot.stop()
diff --git a/tests/tools.py b/tests/tools.py
index 1d62562dc..072b2313e 100644
--- a/tests/tools.py
+++ b/tests/tools.py
@@ -204,17 +204,21 @@ def buildTestProject(obj: object, projPath: Path) -> None:
class SimpleDialog(QDialog):
- def __init__(self, widget: QWidget) -> None:
+ def __init__(self, widget: QWidget | None = None) -> None:
super().__init__()
self._widget = widget
-
layout = QVBoxLayout()
- layout.addWidget(widget)
layout.setContentsMargins(40, 40, 40, 40)
self.setLayout(layout)
-
+ if widget:
+ layout.addWidget(widget)
return
@property
- def widget(self) -> QWidget:
+ def widget(self) -> QWidget | None:
return self._widget
+
+ def addWidget(self, widget: QWidget) -> None:
+ self._widget = widget
+ self.layout().addWidget(widget)
+ return