diff --git a/novelwriter/custom.py b/novelwriter/custom.py
deleted file mode 100644
index 8c766733..00000000
--- a/novelwriter/custom.py
+++ /dev/null
@@ -1,475 +0,0 @@
-"""
-novelWriter – Custom Widgets and Layouts
-========================================
-Various custom widget and layout classes
-
-File History:
-Created: 2020-05-03 [0.4.5] QConfigLayout
-Created: 2020-05-03 [0.4.5] QSwitch
-Created: 2020-05-17 [0.5.1] PagedDialog
-
-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 logging
-import novelwriter
-
-from PyQt5.QtGui import QColor, QPalette, QPainter
-from PyQt5.QtCore import (
- Qt, QRect, QPoint, QRectF, QPropertyAnimation, pyqtProperty
-)
-from PyQt5.QtWidgets import (
- QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QSizePolicy,
- QAbstractButton, QDialog, QTabWidget, QTabBar, QStyle, QStylePainter,
- QStyleOptionTab, QLineEdit
-)
-
-from novelwriter.constants import nwUnicode
-
-logger = logging.getLogger(__name__)
-
-
-# =============================================================================================== #
-# Config Form Layout
-# =============================================================================================== #
-
-class QConfigLayout(QGridLayout):
-
- def __init__(self):
- super().__init__()
-
- self._nextRow = 0
- self._helpCol = QColor(0, 0, 0)
- self._fontScale = 0.9
-
- self._itemMap = {}
-
- wSp = novelwriter.CONFIG.pxInt(8)
- self.setHorizontalSpacing(wSp)
- self.setVerticalSpacing(wSp)
- self.setColumnStretch(0, 1)
-
- return
-
- ##
- # Getters and Setters
- ##
-
- def setHelpTextStyle(self, helpCol, fontScale=0.9):
- """Set the text color for the help text.
- """
- if isinstance(helpCol, QColor):
- self._helpCol = helpCol
- else:
- self._helpCol = QColor(*helpCol)
- self._fontScale = fontScale
- return
-
- def setHelpText(self, intRow, theText):
- """Set the text for the help label.
- """
- if intRow in self._itemMap:
- self._itemMap[intRow]["help"].setText(theText)
- return
-
- def setLabelText(self, intRow, theText):
- """Set the text for the main label.
- """
- if intRow in self._itemMap:
- self._itemMap[intRow]["label"].setText(theText)
- return
-
- ##
- # Class Methods
- ##
-
- def addGroupLabel(self, theLabel):
- """Adds a text label to separate groups of settings.
- """
- if isinstance(theLabel, QLabel):
- qLabel = theLabel
- elif isinstance(theLabel, str):
- qLabel = QLabel("%s" % theLabel)
- else:
- qLabel = None
- raise ValueError("theLabel must be a QLabel")
-
- hM = novelwriter.CONFIG.pxInt(4)
- qLabel.setContentsMargins(0, hM, 0, hM)
- self.addWidget(qLabel, self._nextRow, 0, 1, 2, Qt.AlignLeft)
-
- self.setRowStretch(self._nextRow, 0)
- self.setRowStretch(self._nextRow + 1, 1)
-
- self._nextRow += 1
-
- return
-
- def addRow(self, theLabel, theWidget, helpText=None, theUnit=None, theButton=None):
- """Add a label and a widget as a new row of the grid.
- """
- thisEntry = {
- "label": None,
- "help": None,
- "widget": None,
- }
-
- if isinstance(theLabel, QLabel):
- qLabel = theLabel
- elif isinstance(theLabel, str):
- qLabel = QLabel(theLabel)
- else:
- qLabel = None
- raise ValueError("theLabel must be a QLabel")
-
- if isinstance(theWidget, QWidget):
- qWidget = theWidget
- else:
- qWidget = None
- raise ValueError("theWidget must be a QWidget")
-
- wSp = novelwriter.CONFIG.pxInt(8)
- qLabel.setIndent(wSp)
- if helpText is not None:
- qHelp = QHelpLabel(str(helpText), self._helpCol, self._fontScale)
- qHelp.setIndent(wSp)
-
- labelBox = QVBoxLayout()
- labelBox.addWidget(qLabel)
- labelBox.addWidget(qHelp)
- labelBox.setSpacing(0)
- labelBox.addStretch(1)
-
- thisEntry["help"] = qHelp
- self.addLayout(labelBox, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
-
- else:
- self.addWidget(qLabel, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
-
- if theUnit is not None:
- controlBox = QHBoxLayout()
- controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
- controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter)
- controlBox.setSpacing(wSp)
- self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
-
- elif theButton is not None:
- controlBox = QHBoxLayout()
- controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
- controlBox.addWidget(theButton, 0, Qt.AlignVCenter)
- controlBox.setSpacing(wSp)
- self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
-
- else:
- if isinstance(theWidget, QLineEdit):
- qLayout = QHBoxLayout()
- qLayout.addWidget(theWidget)
- self.addLayout(qLayout, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
- else:
- self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
-
- qLabel.setBuddy(qWidget)
-
- self.setRowStretch(self._nextRow, 0)
- self.setRowStretch(self._nextRow+1, 1)
-
- thisEntry["label"] = qLabel
- thisEntry["widget"] = qWidget
-
- self._itemMap[self._nextRow] = thisEntry
-
- self._nextRow += 1
-
- return self._nextRow - 1
-
-# END Class QConfigLayout
-
-
-class QHelpLabel(QLabel):
-
- def __init__(self, theText, textCol, fontSize=0.9):
- super().__init__(theText)
-
- if isinstance(textCol, QColor):
- qCol = textCol
- else:
- qCol = QColor(*textCol)
-
- lblCol = self.palette()
- lblCol.setColor(QPalette.WindowText, qCol)
- self.setPalette(lblCol)
-
- lblFont = self.font()
- lblFont.setPointSizeF(fontSize*lblFont.pointSizeF())
- self.setFont(lblFont)
-
- self.setWordWrap(True)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
-
- return
-
-# END Class QHelpLabel
-
-
-# =============================================================================================== #
-# Switch Widget
-# =============================================================================================== #
-
-class QSwitch(QAbstractButton):
-
- def __init__(self, parent=None, width=None, height=None):
- super().__init__(parent=parent)
-
- if width is None:
- self._xW = novelwriter.CONFIG.pxInt(40)
- else:
- self._xW = width
-
- if height is None:
- self._xH = novelwriter.CONFIG.pxInt(20)
- else:
- self._xH = height
-
- self._xR = int(self._xH*0.5)
- self._xT = int(self._xH*0.6)
- self._rB = int(novelwriter.CONFIG.guiScale*2)
- self._rH = self._xH - 2*self._rB
- self._rR = self._xR - self._rB
-
- self.setCheckable(True)
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
- self.setFixedWidth(self._xW)
- self.setFixedHeight(self._xH)
- self._offset = self._xR
-
- return
-
- ##
- # Properties
- ##
-
- @pyqtProperty(int)
- def offset(self):
- return self._offset
-
- @offset.setter
- def offset(self, offset):
- self._offset = offset
- self.update()
- return
-
- ##
- # Getters and Setters
- ##
-
- def setChecked(self, checked):
- """Overload setChecked to also alter the offset.
- """
- super().setChecked(checked)
- if checked:
- self.offset = self._xW - self._xR
- else:
- self.offset = self._xR
- return
-
- ##
- # Events
- ##
-
- def resizeEvent(self, event):
- """Overload resize to ensure correct offset.
- """
- super().resizeEvent(event)
- if self.isChecked():
- self.offset = self._xW - self._xR
- else:
- self.offset = self._xR
- return
-
- def paintEvent(self, event):
- """Drawing the switch itself.
- """
- qPaint = QPainter(self)
- qPaint.setRenderHint(QPainter.Antialiasing, True)
- qPaint.setPen(Qt.NoPen)
-
- qPalette = self.palette()
- if self.isChecked():
- trackBrush = qPalette.highlight()
- thumbBrush = qPalette.highlightedText()
- textColor = qPalette.highlight().color()
- thumbText = nwUnicode.U_CHECK
- else:
- trackBrush = qPalette.dark()
- thumbBrush = qPalette.light()
- textColor = qPalette.dark().color()
- thumbText = nwUnicode.U_CROSS
-
- if self.isEnabled():
- trackOpacity = 1.0
- else:
- trackOpacity = 0.6
- trackBrush = qPalette.shadow()
- thumbBrush = qPalette.mid()
- textColor = qPalette.shadow().color()
-
- qPaint.setBrush(trackBrush)
- qPaint.setOpacity(trackOpacity)
- qPaint.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
-
- qPaint.setBrush(thumbBrush)
- qPaint.drawEllipse(self.offset - self._rR, self._rB, self._rH, self._rH)
-
- theFont = qPaint.font()
- theFont.setPixelSize(self._xT)
- qPaint.setPen(textColor)
- qPaint.setFont(theFont)
- qPaint.drawText(
- QRectF(self.offset - self._rR, self._rB, self._rH, self._rH),
- Qt.AlignCenter, thumbText
- )
-
- return
-
- def mouseReleaseEvent(self, event):
- """Animate the switch on mouse release.
- """
- super().mouseReleaseEvent(event)
- if event.button() == Qt.LeftButton:
- doAnim = QPropertyAnimation(self, b"offset", self)
- doAnim.setDuration(120)
- doAnim.setStartValue(self.offset)
- if self.isChecked():
- doAnim.setEndValue(self._xW - self._xR)
- else:
- doAnim.setEndValue(self._xR)
- doAnim.start()
- return
-
- def enterEvent(self, event):
- """Change the cursor when hovering the button.
- """
- self.setCursor(Qt.PointingHandCursor)
- super().enterEvent(event)
- return
-
-# END Class QSwitch
-
-
-# =============================================================================================== #
-# Paged Dialog w/Custom TabWidget
-# =============================================================================================== #
-
-class PagedDialog(QDialog):
-
- def __init__(self, parent=None):
- super().__init__(parent=parent)
-
- self._tabBar = VerticalTabBar(self)
- self._tabBar.setExpanding(False)
-
- self._tabBox = QTabWidget(self)
- self._tabBox.setTabBar(self._tabBar)
- self._tabBox.setTabPosition(QTabWidget.West)
-
- self._buttonBox = QHBoxLayout()
-
- self._outerBox = QVBoxLayout()
- self._outerBox.addWidget(self._tabBox)
- self._outerBox.addLayout(self._buttonBox)
-
- # Default Margins
- thisStyle = self.style()
- mL = thisStyle.pixelMetric(QStyle.PM_LayoutLeftMargin)
- mR = thisStyle.pixelMetric(QStyle.PM_LayoutRightMargin)
- mT = thisStyle.pixelMetric(QStyle.PM_LayoutLeftMargin)
- mB = thisStyle.pixelMetric(QStyle.PM_LayoutBottomMargin)
-
- # Set Margins
- self.setContentsMargins(0, 0, 0, 0)
- self._outerBox.setContentsMargins(0, 0, 0, mB)
- self._buttonBox.setContentsMargins(mL, 0, mR, 0)
- self._outerBox.setSpacing(mT)
-
- self.setLayout(self._outerBox)
-
- return
-
- def addTab(self, widget, label):
- """Forward the adding of tabs to the QTabWidget.
- """
- self._tabBox.addTab(widget, label)
- return
-
- def addControls(self, buttonBar):
- """Add a button bar to the dialog.
- """
- self._buttonBox.addWidget(buttonBar)
- return
-
- def setCurrentWidget(self, widget):
- """Forward the changing of tab to the QTabWidget.
- """
- self._tabBox.setCurrentWidget(widget)
- return
-
-# END Class PagedDialog
-
-
-class VerticalTabBar(QTabBar):
-
- def __init__(self, parent=None):
- super().__init__(parent=parent)
- self._mW = novelwriter.CONFIG.pxInt(150)
- return
-
- def tabSizeHint(self, index):
- """Return a transposed size hint for the rotated bar.
- """
- tSize = super().tabSizeHint(index)
- tSize.transpose()
- tSize.setWidth(min(tSize.width(), self._mW))
- return tSize
-
- def paintEvent(self, event):
- """Custom implementation of the label painter that rotates the
- label 90 degrees.
- """
- pObj = QStylePainter(self)
- oObj = QStyleOptionTab()
-
- for i in range(self.count()):
- self.initStyleOption(oObj, i)
- pObj.drawControl(QStyle.CE_TabBarTabShape, oObj)
- pObj.save()
-
- oSize = oObj.rect.size()
- oSize.transpose()
- oRect = QRect(QPoint(), oSize)
- oRect.moveCenter(oObj.rect.center())
- oObj.rect = oRect
-
- oCenter = self.tabRect(i).center()
- pObj.translate(oCenter)
- pObj.rotate(90)
- pObj.translate(-oCenter)
- pObj.drawControl(QStyle.CE_TabBarTabLabel, oObj)
- pObj.restore()
-
- return
-
-# END Class VerticalTabBar
diff --git a/novelwriter/custom/__init__.py b/novelwriter/custom/__init__.py
new file mode 100644
index 00000000..6e4c5a4e
--- /dev/null
+++ b/novelwriter/custom/__init__.py
@@ -0,0 +1,3 @@
+"""
+novelWriter – Custom Layouts and Widgets
+"""
diff --git a/novelwriter/custom/configlayout.py b/novelwriter/custom/configlayout.py
new file mode 100644
index 00000000..8eadae62
--- /dev/null
+++ b/novelwriter/custom/configlayout.py
@@ -0,0 +1,214 @@
+"""
+novelWriter – Custom Widget: Config Layout
+==========================================
+A custom grid layout for config pages
+
+File History:
+Created: 2020-05-03 [0.4.5]
+
+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 logging
+import novelwriter
+
+from PyQt5.QtGui import QColor, QPalette
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import (
+ QGridLayout, QHBoxLayout, QLabel, QLineEdit, QSizePolicy, QVBoxLayout,
+ QWidget
+)
+
+logger = logging.getLogger(__name__)
+
+
+class NConfigLayout(QGridLayout):
+
+ def __init__(self):
+ super().__init__()
+
+ self._nextRow = 0
+ self._helpCol = QColor(0, 0, 0)
+ self._fontScale = 0.9
+
+ self._itemMap = {}
+
+ wSp = novelwriter.CONFIG.pxInt(8)
+ self.setHorizontalSpacing(wSp)
+ self.setVerticalSpacing(wSp)
+ self.setColumnStretch(0, 1)
+
+ return
+
+ ##
+ # Getters and Setters
+ ##
+
+ def setHelpTextStyle(self, helpCol, fontScale=0.9):
+ """Set the text color for the help text.
+ """
+ if isinstance(helpCol, QColor):
+ self._helpCol = helpCol
+ else:
+ self._helpCol = QColor(*helpCol)
+ self._fontScale = fontScale
+ return
+
+ def setHelpText(self, intRow, theText):
+ """Set the text for the help label.
+ """
+ if intRow in self._itemMap:
+ self._itemMap[intRow]["help"].setText(theText)
+ return
+
+ def setLabelText(self, intRow, theText):
+ """Set the text for the main label.
+ """
+ if intRow in self._itemMap:
+ self._itemMap[intRow]["label"].setText(theText)
+ return
+
+ ##
+ # Class Methods
+ ##
+
+ def addGroupLabel(self, theLabel):
+ """Adds a text label to separate groups of settings.
+ """
+ if isinstance(theLabel, QLabel):
+ qLabel = theLabel
+ elif isinstance(theLabel, str):
+ qLabel = QLabel("%s" % theLabel)
+ else:
+ qLabel = None
+ raise ValueError("theLabel must be a QLabel")
+
+ hM = novelwriter.CONFIG.pxInt(4)
+ qLabel.setContentsMargins(0, hM, 0, hM)
+ self.addWidget(qLabel, self._nextRow, 0, 1, 2, Qt.AlignLeft)
+
+ self.setRowStretch(self._nextRow, 0)
+ self.setRowStretch(self._nextRow + 1, 1)
+
+ self._nextRow += 1
+
+ return
+
+ def addRow(self, theLabel, theWidget, helpText=None, theUnit=None, theButton=None):
+ """Add a label and a widget as a new row of the grid.
+ """
+ thisEntry = {
+ "label": None,
+ "help": None,
+ "widget": None,
+ }
+
+ if isinstance(theLabel, QLabel):
+ qLabel = theLabel
+ elif isinstance(theLabel, str):
+ qLabel = QLabel(theLabel)
+ else:
+ qLabel = None
+ raise ValueError("theLabel must be a QLabel")
+
+ if isinstance(theWidget, QWidget):
+ qWidget = theWidget
+ else:
+ qWidget = None
+ raise ValueError("theWidget must be a QWidget")
+
+ wSp = novelwriter.CONFIG.pxInt(8)
+ qLabel.setIndent(wSp)
+ if helpText is not None:
+ qHelp = NHelpLabel(str(helpText), self._helpCol, self._fontScale)
+ qHelp.setIndent(wSp)
+
+ labelBox = QVBoxLayout()
+ labelBox.addWidget(qLabel)
+ labelBox.addWidget(qHelp)
+ labelBox.setSpacing(0)
+ labelBox.addStretch(1)
+
+ thisEntry["help"] = qHelp
+ self.addLayout(labelBox, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
+
+ else:
+ self.addWidget(qLabel, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
+
+ if theUnit is not None:
+ controlBox = QHBoxLayout()
+ controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
+ controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter)
+ controlBox.setSpacing(wSp)
+ self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
+
+ elif theButton is not None:
+ controlBox = QHBoxLayout()
+ controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
+ controlBox.addWidget(theButton, 0, Qt.AlignVCenter)
+ controlBox.setSpacing(wSp)
+ self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
+
+ else:
+ if isinstance(theWidget, QLineEdit):
+ qLayout = QHBoxLayout()
+ qLayout.addWidget(theWidget)
+ self.addLayout(qLayout, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
+ else:
+ self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop)
+
+ qLabel.setBuddy(qWidget)
+
+ self.setRowStretch(self._nextRow, 0)
+ self.setRowStretch(self._nextRow+1, 1)
+
+ thisEntry["label"] = qLabel
+ thisEntry["widget"] = qWidget
+
+ self._itemMap[self._nextRow] = thisEntry
+
+ self._nextRow += 1
+
+ return self._nextRow - 1
+
+# END Class NConfigLayout
+
+
+class NHelpLabel(QLabel):
+
+ def __init__(self, theText, textCol, fontSize=0.9):
+ super().__init__(theText)
+
+ if isinstance(textCol, QColor):
+ qCol = textCol
+ else:
+ qCol = QColor(*textCol)
+
+ lblCol = self.palette()
+ lblCol.setColor(QPalette.WindowText, qCol)
+ self.setPalette(lblCol)
+
+ lblFont = self.font()
+ lblFont.setPointSizeF(fontSize*lblFont.pointSizeF())
+ self.setFont(lblFont)
+
+ self.setWordWrap(True)
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+
+ return
+
+# END Class NHelpLabel
diff --git a/novelwriter/custom/pageddialog.py b/novelwriter/custom/pageddialog.py
new file mode 100644
index 00000000..47f957fb
--- /dev/null
+++ b/novelwriter/custom/pageddialog.py
@@ -0,0 +1,136 @@
+"""
+novelWriter – Custom Widget: Paged Dialog
+=========================================
+A custom dialog with tabs and a vertical tab bar
+
+File History:
+Created: 2020-05-17 [0.5.1]
+
+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 logging
+import novelwriter
+
+from PyQt5.QtCore import QRect, QPoint
+from PyQt5.QtWidgets import (
+ QDialog, QHBoxLayout, QStyle, QStyleOptionTab, QStylePainter, QTabBar,
+ QTabWidget, QVBoxLayout
+)
+
+logger = logging.getLogger(__name__)
+
+
+class NPagedDialog(QDialog):
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+
+ self._tabBar = NVerticalTabBar(self)
+ self._tabBar.setExpanding(False)
+
+ self._tabBox = QTabWidget(self)
+ self._tabBox.setTabBar(self._tabBar)
+ self._tabBox.setTabPosition(QTabWidget.West)
+
+ self._buttonBox = QHBoxLayout()
+
+ self._outerBox = QVBoxLayout()
+ self._outerBox.addWidget(self._tabBox)
+ self._outerBox.addLayout(self._buttonBox)
+
+ # Default Margins
+ thisStyle = self.style()
+ mL = thisStyle.pixelMetric(QStyle.PM_LayoutLeftMargin)
+ mR = thisStyle.pixelMetric(QStyle.PM_LayoutRightMargin)
+ mT = thisStyle.pixelMetric(QStyle.PM_LayoutLeftMargin)
+ mB = thisStyle.pixelMetric(QStyle.PM_LayoutBottomMargin)
+
+ # Set Margins
+ self.setContentsMargins(0, 0, 0, 0)
+ self._outerBox.setContentsMargins(0, 0, 0, mB)
+ self._buttonBox.setContentsMargins(mL, 0, mR, 0)
+ self._outerBox.setSpacing(mT)
+
+ self.setLayout(self._outerBox)
+
+ return
+
+ def addTab(self, widget, label):
+ """Forward the adding of tabs to the QTabWidget.
+ """
+ self._tabBox.addTab(widget, label)
+ return
+
+ def addControls(self, buttonBar):
+ """Add a button bar to the dialog.
+ """
+ self._buttonBox.addWidget(buttonBar)
+ return
+
+ def setCurrentWidget(self, widget):
+ """Forward the changing of tab to the QTabWidget.
+ """
+ self._tabBox.setCurrentWidget(widget)
+ return
+
+# END Class NPagedDialog
+
+
+class NVerticalTabBar(QTabBar):
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+ self._mW = novelwriter.CONFIG.pxInt(150)
+ return
+
+ def tabSizeHint(self, index):
+ """Return a transposed size hint for the rotated bar.
+ """
+ tSize = super().tabSizeHint(index)
+ tSize.transpose()
+ tSize.setWidth(min(tSize.width(), self._mW))
+ return tSize
+
+ def paintEvent(self, event):
+ """Custom implementation of the label painter that rotates the
+ label 90 degrees.
+ """
+ pObj = QStylePainter(self)
+ oObj = QStyleOptionTab()
+
+ for i in range(self.count()):
+ self.initStyleOption(oObj, i)
+ pObj.drawControl(QStyle.CE_TabBarTabShape, oObj)
+ pObj.save()
+
+ oSize = oObj.rect.size()
+ oSize.transpose()
+ oRect = QRect(QPoint(), oSize)
+ oRect.moveCenter(oObj.rect.center())
+ oObj.rect = oRect
+
+ oCenter = self.tabRect(i).center()
+ pObj.translate(oCenter)
+ pObj.rotate(90)
+ pObj.translate(-oCenter)
+ pObj.drawControl(QStyle.CE_TabBarTabLabel, oObj)
+ pObj.restore()
+
+ return
+
+# END Class NVerticalTabBar
diff --git a/novelwriter/custom/pagedsidebar.py b/novelwriter/custom/pagedsidebar.py
new file mode 100644
index 00000000..485d71a7
--- /dev/null
+++ b/novelwriter/custom/pagedsidebar.py
@@ -0,0 +1,62 @@
+"""
+novelWriter – Custom Widget: Paged SideBar
+==========================================
+A custom widget for making a sidebar for flipping through pages
+
+File History:
+Created: 2023-02-21 [2.1b1] NPagedSideBar
+Created: 2023-02-21 [2.1b1] NToolLabelButton
+
+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 .
+"""
+
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import QToolBar, QToolButton
+
+
+class NPagedSideBar(QToolBar):
+
+ def __init__(self, parent):
+ super().__init__(parent=parent)
+
+ self._buttons = []
+
+ self.setMovable(False)
+ self.setOrientation(Qt.Vertical)
+
+ return
+
+ def addLabel(self, text):
+ """Add a new label to the toolbar.
+ """
+ return
+
+ def addButton(self, text):
+ """Add a new button to the toolbar.
+ """
+ return
+
+# END Class NPagedSideBar
+
+
+class NToolLabelButton(QToolButton):
+
+ def __init__(self, parent):
+ super().__init__(parent=parent)
+ return
+
+# END Class NToolLabelButton
diff --git a/novelwriter/custom/switch.py b/novelwriter/custom/switch.py
new file mode 100644
index 00000000..d57f07b2
--- /dev/null
+++ b/novelwriter/custom/switch.py
@@ -0,0 +1,176 @@
+"""
+novelWriter – Custom Widget: Switch
+===================================
+A custom switch widget
+
+File History:
+Created: 2020-05-03 [0.4.5]
+
+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 logging
+import novelwriter
+
+from PyQt5.QtGui import QPainter
+from PyQt5.QtCore import Qt, QRectF, QPropertyAnimation, pyqtProperty
+from PyQt5.QtWidgets import QSizePolicy, QAbstractButton
+
+from novelwriter.constants import nwUnicode
+
+logger = logging.getLogger(__name__)
+
+
+class NSwitch(QAbstractButton):
+
+ def __init__(self, parent=None, width=None, height=None):
+ super().__init__(parent=parent)
+
+ if width is None:
+ self._xW = novelwriter.CONFIG.pxInt(40)
+ else:
+ self._xW = width
+
+ if height is None:
+ self._xH = novelwriter.CONFIG.pxInt(20)
+ else:
+ self._xH = height
+
+ self._xR = int(self._xH*0.5)
+ self._xT = int(self._xH*0.6)
+ self._rB = int(novelwriter.CONFIG.guiScale*2)
+ self._rH = self._xH - 2*self._rB
+ self._rR = self._xR - self._rB
+
+ self.setCheckable(True)
+ self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ self.setFixedWidth(self._xW)
+ self.setFixedHeight(self._xH)
+ self._offset = self._xR
+
+ return
+
+ ##
+ # Properties
+ ##
+
+ @pyqtProperty(int)
+ def offset(self):
+ return self._offset
+
+ @offset.setter
+ def offset(self, offset):
+ self._offset = offset
+ self.update()
+ return
+
+ ##
+ # Getters and Setters
+ ##
+
+ def setChecked(self, checked):
+ """Overload setChecked to also alter the offset.
+ """
+ super().setChecked(checked)
+ if checked:
+ self.offset = self._xW - self._xR
+ else:
+ self.offset = self._xR
+ return
+
+ ##
+ # Events
+ ##
+
+ def resizeEvent(self, event):
+ """Overload resize to ensure correct offset.
+ """
+ super().resizeEvent(event)
+ if self.isChecked():
+ self.offset = self._xW - self._xR
+ else:
+ self.offset = self._xR
+ return
+
+ def paintEvent(self, event):
+ """Drawing the switch itself.
+ """
+ qPaint = QPainter(self)
+ qPaint.setRenderHint(QPainter.Antialiasing, True)
+ qPaint.setPen(Qt.NoPen)
+
+ qPalette = self.palette()
+ if self.isChecked():
+ trackBrush = qPalette.highlight()
+ thumbBrush = qPalette.highlightedText()
+ textColor = qPalette.highlight().color()
+ thumbText = nwUnicode.U_CHECK
+ else:
+ trackBrush = qPalette.dark()
+ thumbBrush = qPalette.light()
+ textColor = qPalette.dark().color()
+ thumbText = nwUnicode.U_CROSS
+
+ if self.isEnabled():
+ trackOpacity = 1.0
+ else:
+ trackOpacity = 0.6
+ trackBrush = qPalette.shadow()
+ thumbBrush = qPalette.mid()
+ textColor = qPalette.shadow().color()
+
+ qPaint.setBrush(trackBrush)
+ qPaint.setOpacity(trackOpacity)
+ qPaint.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
+
+ qPaint.setBrush(thumbBrush)
+ qPaint.drawEllipse(self.offset - self._rR, self._rB, self._rH, self._rH)
+
+ theFont = qPaint.font()
+ theFont.setPixelSize(self._xT)
+ qPaint.setPen(textColor)
+ qPaint.setFont(theFont)
+ qPaint.drawText(
+ QRectF(self.offset - self._rR, self._rB, self._rH, self._rH),
+ Qt.AlignCenter, thumbText
+ )
+
+ return
+
+ def mouseReleaseEvent(self, event):
+ """Animate the switch on mouse release.
+ """
+ super().mouseReleaseEvent(event)
+ if event.button() == Qt.LeftButton:
+ doAnim = QPropertyAnimation(self, b"offset", self)
+ doAnim.setDuration(120)
+ doAnim.setStartValue(self.offset)
+ if self.isChecked():
+ doAnim.setEndValue(self._xW - self._xR)
+ else:
+ doAnim.setEndValue(self._xR)
+ doAnim.start()
+ return
+
+ def enterEvent(self, event):
+ """Change the cursor when hovering the button.
+ """
+ self.setCursor(Qt.PointingHandCursor)
+ super().enterEvent(event)
+ return
+
+# END Class NSwitch
diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py
index 25c8676f..30e42345 100644
--- a/novelwriter/dialogs/docmerge.py
+++ b/novelwriter/dialogs/docmerge.py
@@ -33,7 +33,8 @@ from PyQt5.QtWidgets import (
QListWidget, QListWidgetItem, QVBoxLayout,
)
-from novelwriter.custom import QHelpLabel, QSwitch
+from novelwriter.custom.switch import NSwitch
+from novelwriter.custom.configlayout import NHelpLabel
logger = logging.getLogger(__name__)
@@ -56,7 +57,7 @@ class GuiDocMerge(QDialog):
self.setWindowTitle(self.tr("Merge Documents"))
self.headLabel = QLabel("{0}".format(self.tr("Documents to Merge")))
- self.helpLabel = QHelpLabel(self.tr(
+ self.helpLabel = NHelpLabel(self.tr(
"Drag and drop items to change the order, or uncheck to exclude."
), self.mainTheme.helpText)
@@ -75,7 +76,7 @@ class GuiDocMerge(QDialog):
# Merge Options
self.trashLabel = QLabel(self.tr("Move merged items to Trash"))
- self.trashSwitch = QSwitch(width=2*iPx, height=iPx)
+ self.trashSwitch = NSwitch(width=2*iPx, height=iPx)
self.optBox = QGridLayout()
self.optBox.addWidget(self.trashLabel, 0, 0)
diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py
index 0db6d6c2..6e534390 100644
--- a/novelwriter/dialogs/docsplit.py
+++ b/novelwriter/dialogs/docsplit.py
@@ -33,7 +33,8 @@ from PyQt5.QtWidgets import (
QListWidgetItem, QDialogButtonBox, QLabel, QGridLayout
)
-from novelwriter.custom import QHelpLabel, QSwitch
+from novelwriter.custom.switch import NSwitch
+from novelwriter.custom.configlayout import NHelpLabel
logger = logging.getLogger(__name__)
@@ -61,7 +62,7 @@ class GuiDocSplit(QDialog):
self.setWindowTitle(self.tr("Split Document"))
self.headLabel = QLabel("{0}".format(self.tr("Document Headers")))
- self.helpLabel = QHelpLabel(
+ self.helpLabel = NHelpLabel(
self.tr("Select the maximum level to split into files."),
self.mainGui.mainTheme.helpText
)
@@ -95,15 +96,15 @@ class GuiDocSplit(QDialog):
# Split Options
self.folderLabel = QLabel(self.tr("Split into a new folder"))
- self.folderSwitch = QSwitch(width=2*iPx, height=iPx)
+ self.folderSwitch = NSwitch(width=2*iPx, height=iPx)
self.folderSwitch.setChecked(intoFolder)
self.hierarchyLabel = QLabel(self.tr("Create document hierarchy"))
- self.hierarchySwitch = QSwitch(width=2*iPx, height=iPx)
+ self.hierarchySwitch = NSwitch(width=2*iPx, height=iPx)
self.hierarchySwitch.setChecked(docHierarchy)
self.trashLabel = QLabel(self.tr("Move split document to Trash"))
- self.trashSwitch = QSwitch(width=2*iPx, height=iPx)
+ self.trashSwitch = NSwitch(width=2*iPx, height=iPx)
self.optBox = QGridLayout()
self.optBox.addWidget(self.folderLabel, 0, 0)
diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py
index 41f4a032..fff952ad 100644
--- a/novelwriter/dialogs/preferences.py
+++ b/novelwriter/dialogs/preferences.py
@@ -33,13 +33,15 @@ from PyQt5.QtWidgets import (
QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox
)
-from novelwriter.custom import QSwitch, QConfigLayout, PagedDialog
+from novelwriter.custom.switch import NSwitch
+from novelwriter.custom.pageddialog import NPagedDialog
+from novelwriter.custom.configlayout import NConfigLayout
from novelwriter.dialogs.quotes import GuiQuoteSelect
logger = logging.getLogger(__name__)
-class GuiPreferences(PagedDialog):
+class GuiPreferences(NPagedDialog):
def __init__(self, mainGui):
super().__init__(parent=mainGui)
@@ -161,7 +163,7 @@ class GuiPreferencesGeneral(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -250,7 +252,7 @@ class GuiPreferencesGeneral(QWidget):
# ============
self.mainForm.addGroupLabel(self.tr("GUI Settings"))
- self.emphLabels = QSwitch()
+ self.emphLabels = NSwitch()
self.emphLabels.setChecked(self.mainConf.emphLabels)
self.mainForm.addRow(
self.tr("Emphasise partition and chapter labels"),
@@ -258,7 +260,7 @@ class GuiPreferencesGeneral(QWidget):
self.tr("Makes them stand out in the project tree."),
)
- self.showFullPath = QSwitch()
+ self.showFullPath = NSwitch()
self.showFullPath.setChecked(self.mainConf.showFullPath)
self.mainForm.addRow(
self.tr("Show full path in document header"),
@@ -266,7 +268,7 @@ class GuiPreferencesGeneral(QWidget):
self.tr("Add the parent folder names to the header.")
)
- self.hideVScroll = QSwitch()
+ self.hideVScroll = NSwitch()
self.hideVScroll.setChecked(self.mainConf.hideVScroll)
self.mainForm.addRow(
self.tr("Hide vertical scroll bars in main windows"),
@@ -274,7 +276,7 @@ class GuiPreferencesGeneral(QWidget):
self.tr("Scrolling available with mouse wheel and keys only.")
)
- self.hideHScroll = QSwitch()
+ self.hideHScroll = NSwitch()
self.hideHScroll.setChecked(self.mainConf.hideHScroll)
self.mainForm.addRow(
self.tr("Hide horizontal scroll bars in main windows"),
@@ -343,7 +345,7 @@ class GuiPreferencesProjects(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -392,7 +394,7 @@ class GuiPreferencesProjects(QWidget):
)
# Run when closing
- self.backupOnClose = QSwitch()
+ self.backupOnClose = NSwitch()
self.backupOnClose.setChecked(self.mainConf.backupOnClose)
self.backupOnClose.toggled.connect(self._toggledBackupOnClose)
self.mainForm.addRow(
@@ -403,7 +405,7 @@ class GuiPreferencesProjects(QWidget):
# Ask before backup
# Only enabled when "Run when closing" is checked
- self.askBeforeBackup = QSwitch()
+ self.askBeforeBackup = NSwitch()
self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup)
self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose)
self.mainForm.addRow(
@@ -417,7 +419,7 @@ class GuiPreferencesProjects(QWidget):
self.mainForm.addGroupLabel(self.tr("Session Timer"))
# Pause when idle
- self.stopWhenIdle = QSwitch()
+ self.stopWhenIdle = NSwitch()
self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle)
self.mainForm.addRow(
self.tr("Pause the session timer when not writing"),
@@ -499,7 +501,7 @@ class GuiPreferencesDocuments(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -566,7 +568,7 @@ class GuiPreferencesDocuments(QWidget):
)
# Focus Mode Footer
- self.hideFocusFooter = QSwitch()
+ self.hideFocusFooter = NSwitch()
self.hideFocusFooter.setChecked(self.mainConf.hideFocusFooter)
self.mainForm.addRow(
self.tr("Hide document footer in \"Focus Mode\""),
@@ -575,7 +577,7 @@ class GuiPreferencesDocuments(QWidget):
)
# Justify Text
- self.doJustify = QSwitch()
+ self.doJustify = NSwitch()
self.doJustify.setChecked(self.mainConf.doJustify)
self.mainForm.addRow(
self.tr("Justify the text margins"),
@@ -658,7 +660,7 @@ class GuiPreferencesEditor(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -727,7 +729,7 @@ class GuiPreferencesEditor(QWidget):
)
# Include Notes in Word Count
- self.incNotesWCount = QSwitch()
+ self.incNotesWCount = NSwitch()
self.incNotesWCount.setChecked(self.mainConf.incNotesWCount)
self.mainForm.addRow(
self.tr("Include project notes in status bar word count"),
@@ -739,7 +741,7 @@ class GuiPreferencesEditor(QWidget):
self.mainForm.addGroupLabel(self.tr("Writing Guides"))
# Show Tabs and Spaces
- self.showTabsNSpaces = QSwitch()
+ self.showTabsNSpaces = NSwitch()
self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces)
self.mainForm.addRow(
self.tr("Show tabs and spaces"),
@@ -747,7 +749,7 @@ class GuiPreferencesEditor(QWidget):
)
# Show Line Endings
- self.showLineEndings = QSwitch()
+ self.showLineEndings = NSwitch()
self.showLineEndings.setChecked(self.mainConf.showLineEndings)
self.mainForm.addRow(
self.tr("Show line endings"),
@@ -772,7 +774,7 @@ class GuiPreferencesEditor(QWidget):
)
# Typewriter Scrolling
- self.autoScroll = QSwitch()
+ self.autoScroll = NSwitch()
self.autoScroll.setChecked(self.mainConf.autoScroll)
self.mainForm.addRow(
self.tr("Typewriter style scrolling when you type"),
@@ -831,7 +833,7 @@ class GuiPreferencesSyntax(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -839,7 +841,7 @@ class GuiPreferencesSyntax(QWidget):
# =================
self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue"))
- self.highlightQuotes = QSwitch()
+ self.highlightQuotes = NSwitch()
self.highlightQuotes.setChecked(self.mainConf.highlightQuotes)
self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes)
self.mainForm.addRow(
@@ -848,7 +850,7 @@ class GuiPreferencesSyntax(QWidget):
self.tr("Applies to the document editor only.")
)
- self.allowOpenSQuote = QSwitch()
+ self.allowOpenSQuote = NSwitch()
self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote)
self.mainForm.addRow(
self.tr("Allow open-ended single quotes"),
@@ -856,7 +858,7 @@ class GuiPreferencesSyntax(QWidget):
self.tr("Highlight single-quoted line with no closing quote.")
)
- self.allowOpenDQuote = QSwitch()
+ self.allowOpenDQuote = NSwitch()
self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote)
self.mainForm.addRow(
self.tr("Allow open-ended double quotes"),
@@ -868,7 +870,7 @@ class GuiPreferencesSyntax(QWidget):
# =============
self.mainForm.addGroupLabel(self.tr("Text Emphasis"))
- self.highlightEmph = QSwitch()
+ self.highlightEmph = NSwitch()
self.highlightEmph.setChecked(self.mainConf.highlightEmph)
self.mainForm.addRow(
self.tr("Add highlight colour to emphasised text"),
@@ -881,7 +883,7 @@ class GuiPreferencesSyntax(QWidget):
self.mainForm.addGroupLabel(self.tr("Text Errors"))
- self.showMultiSpaces = QSwitch()
+ self.showMultiSpaces = NSwitch()
self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces)
self.mainForm.addRow(
self.tr("Highlight multiple or trailing spaces"),
@@ -937,7 +939,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -946,7 +948,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainForm.addGroupLabel(self.tr("Automatic Features"))
# Auto-Select Word Under Cursor
- self.autoSelect = QSwitch()
+ self.autoSelect = NSwitch()
self.autoSelect.setChecked(self.mainConf.autoSelect)
self.mainForm.addRow(
self.tr("Auto-select word under cursor"),
@@ -955,7 +957,7 @@ class GuiPreferencesAutomation(QWidget):
)
# Auto-Replace as You Type Main Switch
- self.doReplace = QSwitch()
+ self.doReplace = NSwitch()
self.doReplace.setChecked(self.mainConf.doReplace)
self.doReplace.toggled.connect(self._toggleAutoReplaceMain)
self.mainForm.addRow(
@@ -969,7 +971,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainForm.addGroupLabel(self.tr("Replace as You Type"))
# Auto-Replace Single Quotes
- self.doReplaceSQuote = QSwitch()
+ self.doReplaceSQuote = NSwitch()
self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote)
self.doReplaceSQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
@@ -979,7 +981,7 @@ class GuiPreferencesAutomation(QWidget):
)
# Auto-Replace Double Quotes
- self.doReplaceDQuote = QSwitch()
+ self.doReplaceDQuote = NSwitch()
self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote)
self.doReplaceDQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
@@ -989,7 +991,7 @@ class GuiPreferencesAutomation(QWidget):
)
# Auto-Replace Hyphens
- self.doReplaceDash = QSwitch()
+ self.doReplaceDash = NSwitch()
self.doReplaceDash.setChecked(self.mainConf.doReplaceDash)
self.doReplaceDash.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
@@ -999,7 +1001,7 @@ class GuiPreferencesAutomation(QWidget):
)
# Auto-Replace Dots
- self.doReplaceDots = QSwitch()
+ self.doReplaceDots = NSwitch()
self.doReplaceDots.setChecked(self.mainConf.doReplaceDots)
self.doReplaceDots.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
@@ -1033,7 +1035,7 @@ class GuiPreferencesAutomation(QWidget):
)
# Use Thin Space
- self.fmtPadThin = QSwitch()
+ self.fmtPadThin = NSwitch()
self.fmtPadThin.setChecked(self.mainConf.fmtPadThin)
self.fmtPadThin.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
@@ -1092,7 +1094,7 @@ class GuiPreferencesQuotes(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm)
diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py
index 35d52345..02a31478 100644
--- a/novelwriter/dialogs/projdetails.py
+++ b/novelwriter/dialogs/projdetails.py
@@ -35,14 +35,15 @@ from PyQt5.QtWidgets import (
)
from novelwriter.common import formatTime, numberToRoman
-from novelwriter.custom import PagedDialog, QSwitch
from novelwriter.constants import nwUnicode
+from novelwriter.custom.switch import NSwitch
+from novelwriter.custom.pageddialog import NPagedDialog
from novelwriter.gui.components import NovelSelector
logger = logging.getLogger(__name__)
-class GuiProjectDetails(PagedDialog):
+class GuiProjectDetails(NPagedDialog):
def __init__(self, mainGui):
super().__init__(parent=mainGui)
@@ -386,7 +387,7 @@ class GuiProjectDetailsContents(QWidget):
self.dblLabel = QLabel(self.tr("Clear double pages"))
self.dblLabel.setToolTip(dblHelp)
- self.dblValue = QSwitch(self, 2*iPx, iPx)
+ self.dblValue = NSwitch(self, 2*iPx, iPx)
self.dblValue.setChecked(clearDouble)
self.dblValue.setToolTip(dblHelp)
self.dblValue.clicked.connect(self._populateTree)
diff --git a/novelwriter/dialogs/projsettings.py b/novelwriter/dialogs/projsettings.py
index 23fb28c5..b406701f 100644
--- a/novelwriter/dialogs/projsettings.py
+++ b/novelwriter/dialogs/projsettings.py
@@ -35,12 +35,14 @@ from PyQt5.QtWidgets import (
from novelwriter.enum import nwAlert
from novelwriter.common import simplified
-from novelwriter.custom import QSwitch, PagedDialog, QConfigLayout
+from novelwriter.custom.switch import NSwitch
+from novelwriter.custom.pageddialog import NPagedDialog
+from novelwriter.custom.configlayout import NConfigLayout
logger = logging.getLogger(__name__)
-class GuiProjectSettings(PagedDialog):
+class GuiProjectSettings(NPagedDialog):
TAB_MAIN = 0
TAB_STATUS = 1
@@ -196,7 +198,7 @@ class GuiProjectEditMain(QWidget):
self.theProject = projGui.theProject
# The Form
- self.mainForm = QConfigLayout()
+ self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainGui.mainTheme.helpText)
self.setLayout(self.mainForm)
@@ -255,7 +257,7 @@ class GuiProjectEditMain(QWidget):
if spellIdx != -1:
self.spellLang.setCurrentIndex(spellIdx)
- self.doBackup = QSwitch(self)
+ self.doBackup = NSwitch(self)
self.doBackup.setChecked(not self.theProject.data.doBackup)
self.mainForm.addRow(
self.tr("No backup on close"),
diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py
index c27c8311..79ea27af 100644
--- a/novelwriter/gui/sidebar.py
+++ b/novelwriter/gui/sidebar.py
@@ -1,6 +1,6 @@
"""
novelWriter – GUI Main Window SideBar
-===========================================
+=====================================
GUI class for the main window side bar
File History:
diff --git a/novelwriter/tools/build.py b/novelwriter/tools/build.py
index f6f9ccd8..c1cdf291 100644
--- a/novelwriter/tools/build.py
+++ b/novelwriter/tools/build.py
@@ -46,11 +46,11 @@ from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from novelwriter.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass
from novelwriter.error import formatException, logException
from novelwriter.common import fuzzyTime, makeFileNameSafe
-from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles
from novelwriter.core.tomd import ToMarkdown
from novelwriter.core.toodt import ToOdt
from novelwriter.core.tohtml import ToHtml
+from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__)
@@ -174,12 +174,12 @@ class GuiBuildNovel(QDialog):
if langIdx != -1:
self.buildLang.setCurrentIndex(langIdx)
- self.hideScene = QSwitch(width=wS, height=hS)
+ self.hideScene = NSwitch(width=wS, height=hS)
self.hideScene.setChecked(
pOptions.getBool("GuiBuildNovel", "hideScene", False)
)
- self.hideSection = QSwitch(width=wS, height=hS)
+ self.hideSection = NSwitch(width=wS, height=hS)
self.hideSection.setChecked(
pOptions.getBool("GuiBuildNovel", "hideSection", True)
)
@@ -291,12 +291,12 @@ class GuiBuildNovel(QDialog):
self.styleForm = QGridLayout(self)
self.styleGroup.setLayout(self.styleForm)
- self.justifyText = QSwitch(width=wS, height=hS)
+ self.justifyText = NSwitch(width=wS, height=hS)
self.justifyText.setChecked(
pOptions.getBool("GuiBuildNovel", "justifyText", False)
)
- self.noStyling = QSwitch(width=wS, height=hS)
+ self.noStyling = NSwitch(width=wS, height=hS)
self.noStyling.setChecked(
pOptions.getBool("GuiBuildNovel", "noStyling", False)
)
@@ -316,22 +316,22 @@ class GuiBuildNovel(QDialog):
self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm)
- self.includeSynopsis = QSwitch(width=wS, height=hS)
+ self.includeSynopsis = NSwitch(width=wS, height=hS)
self.includeSynopsis.setChecked(
pOptions.getBool("GuiBuildNovel", "incSynopsis", False)
)
- self.includeComments = QSwitch(width=wS, height=hS)
+ self.includeComments = NSwitch(width=wS, height=hS)
self.includeComments.setChecked(
pOptions.getBool("GuiBuildNovel", "incComments", False)
)
- self.includeKeywords = QSwitch(width=wS, height=hS)
+ self.includeKeywords = NSwitch(width=wS, height=hS)
self.includeKeywords.setChecked(
pOptions.getBool("GuiBuildNovel", "incKeywords", False)
)
- self.includeBody = QSwitch(width=wS, height=hS)
+ self.includeBody = NSwitch(width=wS, height=hS)
self.includeBody.setChecked(
pOptions.getBool("GuiBuildNovel", "incBodyText", True)
)
@@ -371,7 +371,7 @@ class GuiBuildNovel(QDialog):
rootLabel = QLabel(nwItem.itemName)
rootLabel.setWordWrap(True)
- rootValue = QSwitch(width=wS, height=hS)
+ rootValue = NSwitch(width=wS, height=hS)
rootValue.setChecked(tHandle not in rootFilter)
self.rootSelection[tHandle] = rootValue
@@ -390,17 +390,17 @@ class GuiBuildNovel(QDialog):
self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm)
- self.novelFiles = QSwitch(width=wS, height=hS)
+ self.novelFiles = NSwitch(width=wS, height=hS)
self.novelFiles.setChecked(
pOptions.getBool("GuiBuildNovel", "addNovel", True)
)
- self.noteFiles = QSwitch(width=wS, height=hS)
+ self.noteFiles = NSwitch(width=wS, height=hS)
self.noteFiles.setChecked(
pOptions.getBool("GuiBuildNovel", "addNotes", False)
)
- self.ignoreFlag = QSwitch(width=wS, height=hS)
+ self.ignoreFlag = NSwitch(width=wS, height=hS)
self.ignoreFlag.setChecked(
pOptions.getBool("GuiBuildNovel", "ignoreFlag", False)
)
@@ -426,12 +426,12 @@ class GuiBuildNovel(QDialog):
self.exportForm = QGridLayout(self)
self.exportGroup.setLayout(self.exportForm)
- self.replaceTabs = QSwitch(width=wS, height=hS)
+ self.replaceTabs = NSwitch(width=wS, height=hS)
self.replaceTabs.setChecked(
pOptions.getBool("GuiBuildNovel", "replaceTabs", False)
)
- self.replaceUCode = QSwitch(width=wS, height=hS)
+ self.replaceUCode = NSwitch(width=wS, height=hS)
self.replaceUCode.setChecked(
pOptions.getBool("GuiBuildNovel", "replaceUCode", False)
)
diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py
index 9f0679c4..e4db9f66 100644
--- a/novelwriter/tools/lipsum.py
+++ b/novelwriter/tools/lipsum.py
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
)
from novelwriter.common import readTextFile
-from novelwriter.custom import QSwitch
+from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__)
@@ -78,7 +78,7 @@ class GuiLipsum(QDialog):
self.paraCount.setValue(5)
self.randLabel = QLabel(self.tr("Randomise order"))
- self.randSwitch = QSwitch()
+ self.randSwitch = NSwitch()
self.formBox = QGridLayout()
self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignLeft)
diff --git a/novelwriter/tools/projwizard.py b/novelwriter/tools/projwizard.py
index 3dee4861..8fdf2c8c 100644
--- a/novelwriter/tools/projwizard.py
+++ b/novelwriter/tools/projwizard.py
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
)
from novelwriter.common import makeFileNameSafe
-from novelwriter.custom import QSwitch
+from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__)
@@ -328,19 +328,19 @@ class ProjWizardCustomPage(QWizardPage):
fS = self.mainConf.pxInt(4)
# Root Folders
- self.addPlot = QSwitch()
+ self.addPlot = NSwitch()
self.addPlot.setChecked(True)
self.addPlot.clicked.connect(self._syncSwitches)
- self.addChar = QSwitch()
+ self.addChar = NSwitch()
self.addChar.setChecked(True)
self.addChar.clicked.connect(self._syncSwitches)
- self.addWorld = QSwitch()
+ self.addWorld = NSwitch()
self.addWorld.setChecked(False)
self.addWorld.clicked.connect(self._syncSwitches)
- self.addNotes = QSwitch()
+ self.addNotes = NSwitch()
self.addNotes.setChecked(False)
# Generate Content
diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py
index a5981985..93da7f63 100644
--- a/novelwriter/tools/writingstats.py
+++ b/novelwriter/tools/writingstats.py
@@ -40,8 +40,8 @@ from PyQt5.QtWidgets import (
from novelwriter.enum import nwAlert
from novelwriter.error import formatException
from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax
-from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles
+from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__)
@@ -190,37 +190,37 @@ class GuiWritingStats(QDialog):
self.filterForm = QGridLayout(self)
self.filterBox.setLayout(self.filterForm)
- self.incNovel = QSwitch(width=2*sPx, height=sPx)
+ self.incNovel = NSwitch(width=2*sPx, height=sPx)
self.incNovel.setChecked(
pOptions.getBool("GuiWritingStats", "incNovel", True)
)
self.incNovel.clicked.connect(self._updateListBox)
- self.incNotes = QSwitch(width=2*sPx, height=sPx)
+ self.incNotes = NSwitch(width=2*sPx, height=sPx)
self.incNotes.setChecked(
pOptions.getBool("GuiWritingStats", "incNotes", True)
)
self.incNotes.clicked.connect(self._updateListBox)
- self.hideZeros = QSwitch(width=2*sPx, height=sPx)
+ self.hideZeros = NSwitch(width=2*sPx, height=sPx)
self.hideZeros.setChecked(
pOptions.getBool("GuiWritingStats", "hideZeros", True)
)
self.hideZeros.clicked.connect(self._updateListBox)
- self.hideNegative = QSwitch(width=2*sPx, height=sPx)
+ self.hideNegative = NSwitch(width=2*sPx, height=sPx)
self.hideNegative.setChecked(
pOptions.getBool("GuiWritingStats", "hideNegative", False)
)
self.hideNegative.clicked.connect(self._updateListBox)
- self.groupByDay = QSwitch(width=2*sPx, height=sPx)
+ self.groupByDay = NSwitch(width=2*sPx, height=sPx)
self.groupByDay.setChecked(
pOptions.getBool("GuiWritingStats", "groupByDay", False)
)
self.groupByDay.clicked.connect(self._updateListBox)
- self.showIdleTime = QSwitch(width=2*sPx, height=sPx)
+ self.showIdleTime = NSwitch(width=2*sPx, height=sPx)
self.showIdleTime.setChecked(
pOptions.getBool("GuiWritingStats", "showIdleTime", False)
)