From 29386e8595d342a37bcf44cdc80a9923188916c1 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:19:09 +0200 Subject: [PATCH] Add a switch box widget and use it for filter options in build --- novelwriter/extensions/configlayout.py | 3 - novelwriter/extensions/pageddialog.py | 3 - novelwriter/extensions/switch.py | 3 - novelwriter/extensions/switchbox.py | 119 +++++++++++++++++++++++++ novelwriter/tools/mbuild.py | 26 +++++- 5 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 novelwriter/extensions/switchbox.py diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index 8eadae62..129400e2 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -23,7 +23,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import logging import novelwriter from PyQt5.QtGui import QColor, QPalette @@ -33,8 +32,6 @@ from PyQt5.QtWidgets import ( QWidget ) -logger = logging.getLogger(__name__) - class NConfigLayout(QGridLayout): diff --git a/novelwriter/extensions/pageddialog.py b/novelwriter/extensions/pageddialog.py index 47f957fb..ec22767b 100644 --- a/novelwriter/extensions/pageddialog.py +++ b/novelwriter/extensions/pageddialog.py @@ -23,7 +23,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import logging import novelwriter from PyQt5.QtCore import QRect, QPoint @@ -32,8 +31,6 @@ from PyQt5.QtWidgets import ( QTabWidget, QVBoxLayout ) -logger = logging.getLogger(__name__) - class NPagedDialog(QDialog): diff --git a/novelwriter/extensions/switch.py b/novelwriter/extensions/switch.py index d57f07b2..ab1efa9a 100644 --- a/novelwriter/extensions/switch.py +++ b/novelwriter/extensions/switch.py @@ -23,7 +23,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import logging import novelwriter from PyQt5.QtGui import QPainter @@ -32,8 +31,6 @@ from PyQt5.QtWidgets import QSizePolicy, QAbstractButton from novelwriter.constants import nwUnicode -logger = logging.getLogger(__name__) - class NSwitch(QAbstractButton): diff --git a/novelwriter/extensions/switchbox.py b/novelwriter/extensions/switchbox.py new file mode 100644 index 00000000..45d7680f --- /dev/null +++ b/novelwriter/extensions/switchbox.py @@ -0,0 +1,119 @@ +""" +novelWriter – Custom Widget: Switch Box +======================================= +A box of icons, labels and switches + +File History: +Created: 2023-04-16 [2.1b1] + +This file is a part of novelWriter +Copyright 2018–2023, 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 . +""" + +import novelwriter + +from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QSizePolicy, QWidget + +from novelwriter.extensions.switch import NSwitch + + +class NSwitchBox(QScrollArea): + + switchToggled = pyqtSignal(str, bool) + + def __init__(self, parent, baseSize): + super().__init__(parent=parent) + + self.mainConf = novelwriter.CONFIG + + self._index = 0 + self._hSwitch = baseSize + self._wSwitch = 2*self._hSwitch + self._sIcon = int(round(0.8*baseSize)) + + self._content = QGridLayout() + self._content.setColumnStretch(1, 1) + + self._widget = QWidget() + self._widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) + self._widget.setLayout(self._content) + + self.setWidgetResizable(True) + self.setWidget(self._widget) + + return + + def addLabel(self, text): + """Add a header label to the content box. + """ + label = QLabel(text) + font = label.font() + font.setBold(True) + label.setFont(font) + self._content.addWidget(label, self._index, 0, 1, 3, Qt.AlignLeft) + self._bumpIndex() + return + + def addItem(self, qIcon, text, identifier, default=False): + """Add an item to the content box. + """ + icon = QLabel("") + icon.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + icon.setPixmap(qIcon.pixmap(self._sIcon, self._sIcon)) + self._content.addWidget(icon, self._index, 0, Qt.AlignLeft) + + label = QLabel(text) + self._content.addWidget(label, self._index, 1, Qt.AlignLeft) + + switch = NSwitch(width=self._wSwitch, height=self._hSwitch) + switch.setChecked(default) + switch.toggled.connect(lambda state: self._emitSwitchSignal(identifier, state)) + self._content.addWidget(switch, self._index, 2, Qt.AlignRight) + + self._bumpIndex() + + return + + def addSeparator(self): + """Add a blank entry in the content box. + """ + spacer = QWidget() + spacer.setFixedHeight(int(0.5*self._sIcon)) + self._content.addWidget(spacer, self._index, 0, 1, 3, Qt.AlignLeft) + self._bumpIndex() + return + + ## + # Internal Functions + ## + + def _emitSwitchSignal(self, identifier, state): + """Emit a signal for a switch toggle. + """ + self.switchToggled.emit(identifier, state) + return + + def _bumpIndex(self): + """Increase the index counter and make sure only the last + columns is stretcing. + """ + self._content.setRowStretch(self._index, 0) + self._content.setRowStretch(self._index + 1, 1) + self._index += 1 + return + +# END Class NSwitchBox diff --git a/novelwriter/tools/mbuild.py b/novelwriter/tools/mbuild.py index 39c2d20e..11cabb0e 100644 --- a/novelwriter/tools/mbuild.py +++ b/novelwriter/tools/mbuild.py @@ -24,16 +24,18 @@ along with this program. If not, see . """ import logging + import novelwriter from PyQt5.QtGui import QIcon from PyQt5.QtCore import QSize, Qt, pyqtSlot from PyQt5.QtWidgets import ( - QAbstractItemView, QDialog, QHBoxLayout, QHeaderView, QPushButton, QStackedWidget, - QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget + QAbstractItemView, QDialog, QHBoxLayout, QHeaderView, QPushButton, + QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) from novelwriter.core.buildsettings import BuildSettings +from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.pagedsidebar import NPagedSideBar logger = logging.getLogger(__name__) @@ -242,10 +244,28 @@ class GuiBuildFilterTab(QWidget): self.modeBox.addWidget(self.includedButton) self.modeBox.addWidget(self.excludedButton) + # Filer Options + self.filterOpt = NSwitchBox(self, iPx) + + self.filterOpt.addLabel(self.tr("Document Types")) + self.filterOpt.addItem(QIcon(), "Novel Documents", "doc:novel") + self.filterOpt.addItem(QIcon(), "Project Notes", "doc:notes") + self.filterOpt.addItem(QIcon(), "Inactive Documents", "doc:inactive") + self.filterOpt.addSeparator() + + # Root Classes + self.filterOpt.addLabel(self.tr("Root Folders")) + for tHandle, nwItem in self.theProject.tree.iterRoots(None): + if not nwItem.isInactiveClass(): + itemIcon = self.mainTheme.getItemIcon( + nwItem.itemType, nwItem.itemClass, nwItem.itemLayout + ) + self.filterOpt.addItem(itemIcon, nwItem.itemName, f"root:{tHandle}") + # Assemble self.selectionBox = QVBoxLayout() self.selectionBox.addLayout(self.modeBox) - self.selectionBox.addStretch() + self.selectionBox.addWidget(self.filterOpt) self.outerBox = QHBoxLayout() self.outerBox.addWidget(self.optTree)