Add a custom widgets subpackage

This commit is contained in:
Veronica Berglyd Olsen
2023-02-21 16:06:41 +01:00
parent 06407a44d3
commit 7a60d8d867
16 changed files with 677 additions and 554 deletions
-475
View File
@@ -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 20182023, 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 <https://www.gnu.org/licenses/>.
"""
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("<b>%s</b>" % 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
+3
View File
@@ -0,0 +1,3 @@
"""
novelWriter Custom Layouts and Widgets
"""
+214
View File
@@ -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 20182023, 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 <https://www.gnu.org/licenses/>.
"""
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("<b>%s</b>" % 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
+136
View File
@@ -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 20182023, 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 <https://www.gnu.org/licenses/>.
"""
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
+62
View File
@@ -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 20182023, 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 <https://www.gnu.org/licenses/>.
"""
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
+176
View File
@@ -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 20182023, 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 <https://www.gnu.org/licenses/>.
"""
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
+4 -3
View File
@@ -33,7 +33,8 @@ from PyQt5.QtWidgets import (
QListWidget, QListWidgetItem, QVBoxLayout, 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__) logger = logging.getLogger(__name__)
@@ -56,7 +57,7 @@ class GuiDocMerge(QDialog):
self.setWindowTitle(self.tr("Merge Documents")) self.setWindowTitle(self.tr("Merge Documents"))
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Documents to Merge"))) self.headLabel = QLabel("<b>{0}</b>".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." "Drag and drop items to change the order, or uncheck to exclude."
), self.mainTheme.helpText) ), self.mainTheme.helpText)
@@ -75,7 +76,7 @@ class GuiDocMerge(QDialog):
# Merge Options # Merge Options
self.trashLabel = QLabel(self.tr("Move merged items to Trash")) 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 = QGridLayout()
self.optBox.addWidget(self.trashLabel, 0, 0) self.optBox.addWidget(self.trashLabel, 0, 0)
+6 -5
View File
@@ -33,7 +33,8 @@ from PyQt5.QtWidgets import (
QListWidgetItem, QDialogButtonBox, QLabel, QGridLayout 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__) logger = logging.getLogger(__name__)
@@ -61,7 +62,7 @@ class GuiDocSplit(QDialog):
self.setWindowTitle(self.tr("Split Document")) self.setWindowTitle(self.tr("Split Document"))
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headers"))) self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headers")))
self.helpLabel = QHelpLabel( self.helpLabel = NHelpLabel(
self.tr("Select the maximum level to split into files."), self.tr("Select the maximum level to split into files."),
self.mainGui.mainTheme.helpText self.mainGui.mainTheme.helpText
) )
@@ -95,15 +96,15 @@ class GuiDocSplit(QDialog):
# Split Options # Split Options
self.folderLabel = QLabel(self.tr("Split into a new folder")) 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.folderSwitch.setChecked(intoFolder)
self.hierarchyLabel = QLabel(self.tr("Create document hierarchy")) 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.hierarchySwitch.setChecked(docHierarchy)
self.trashLabel = QLabel(self.tr("Move split document to Trash")) 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 = QGridLayout()
self.optBox.addWidget(self.folderLabel, 0, 0) self.optBox.addWidget(self.folderLabel, 0, 0)
+36 -34
View File
@@ -33,13 +33,15 @@ from PyQt5.QtWidgets import (
QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox 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 from novelwriter.dialogs.quotes import GuiQuoteSelect
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiPreferences(PagedDialog): class GuiPreferences(NPagedDialog):
def __init__(self, mainGui): def __init__(self, mainGui):
super().__init__(parent=mainGui) super().__init__(parent=mainGui)
@@ -161,7 +163,7 @@ class GuiPreferencesGeneral(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -250,7 +252,7 @@ class GuiPreferencesGeneral(QWidget):
# ============ # ============
self.mainForm.addGroupLabel(self.tr("GUI Settings")) self.mainForm.addGroupLabel(self.tr("GUI Settings"))
self.emphLabels = QSwitch() self.emphLabels = NSwitch()
self.emphLabels.setChecked(self.mainConf.emphLabels) self.emphLabels.setChecked(self.mainConf.emphLabels)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Emphasise partition and chapter labels"), 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.tr("Makes them stand out in the project tree."),
) )
self.showFullPath = QSwitch() self.showFullPath = NSwitch()
self.showFullPath.setChecked(self.mainConf.showFullPath) self.showFullPath.setChecked(self.mainConf.showFullPath)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Show full path in document header"), 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.tr("Add the parent folder names to the header.")
) )
self.hideVScroll = QSwitch() self.hideVScroll = NSwitch()
self.hideVScroll.setChecked(self.mainConf.hideVScroll) self.hideVScroll.setChecked(self.mainConf.hideVScroll)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Hide vertical scroll bars in main windows"), 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.tr("Scrolling available with mouse wheel and keys only.")
) )
self.hideHScroll = QSwitch() self.hideHScroll = NSwitch()
self.hideHScroll.setChecked(self.mainConf.hideHScroll) self.hideHScroll.setChecked(self.mainConf.hideHScroll)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Hide horizontal scroll bars in main windows"), self.tr("Hide horizontal scroll bars in main windows"),
@@ -343,7 +345,7 @@ class GuiPreferencesProjects(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -392,7 +394,7 @@ class GuiPreferencesProjects(QWidget):
) )
# Run when closing # Run when closing
self.backupOnClose = QSwitch() self.backupOnClose = NSwitch()
self.backupOnClose.setChecked(self.mainConf.backupOnClose) self.backupOnClose.setChecked(self.mainConf.backupOnClose)
self.backupOnClose.toggled.connect(self._toggledBackupOnClose) self.backupOnClose.toggled.connect(self._toggledBackupOnClose)
self.mainForm.addRow( self.mainForm.addRow(
@@ -403,7 +405,7 @@ class GuiPreferencesProjects(QWidget):
# Ask before backup # Ask before backup
# Only enabled when "Run when closing" is checked # Only enabled when "Run when closing" is checked
self.askBeforeBackup = QSwitch() self.askBeforeBackup = NSwitch()
self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup) self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup)
self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose) self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose)
self.mainForm.addRow( self.mainForm.addRow(
@@ -417,7 +419,7 @@ class GuiPreferencesProjects(QWidget):
self.mainForm.addGroupLabel(self.tr("Session Timer")) self.mainForm.addGroupLabel(self.tr("Session Timer"))
# Pause when idle # Pause when idle
self.stopWhenIdle = QSwitch() self.stopWhenIdle = NSwitch()
self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle) self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Pause the session timer when not writing"), self.tr("Pause the session timer when not writing"),
@@ -499,7 +501,7 @@ class GuiPreferencesDocuments(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -566,7 +568,7 @@ class GuiPreferencesDocuments(QWidget):
) )
# Focus Mode Footer # Focus Mode Footer
self.hideFocusFooter = QSwitch() self.hideFocusFooter = NSwitch()
self.hideFocusFooter.setChecked(self.mainConf.hideFocusFooter) self.hideFocusFooter.setChecked(self.mainConf.hideFocusFooter)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Hide document footer in \"Focus Mode\""), self.tr("Hide document footer in \"Focus Mode\""),
@@ -575,7 +577,7 @@ class GuiPreferencesDocuments(QWidget):
) )
# Justify Text # Justify Text
self.doJustify = QSwitch() self.doJustify = NSwitch()
self.doJustify.setChecked(self.mainConf.doJustify) self.doJustify.setChecked(self.mainConf.doJustify)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Justify the text margins"), self.tr("Justify the text margins"),
@@ -658,7 +660,7 @@ class GuiPreferencesEditor(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -727,7 +729,7 @@ class GuiPreferencesEditor(QWidget):
) )
# Include Notes in Word Count # Include Notes in Word Count
self.incNotesWCount = QSwitch() self.incNotesWCount = NSwitch()
self.incNotesWCount.setChecked(self.mainConf.incNotesWCount) self.incNotesWCount.setChecked(self.mainConf.incNotesWCount)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Include project notes in status bar word count"), self.tr("Include project notes in status bar word count"),
@@ -739,7 +741,7 @@ class GuiPreferencesEditor(QWidget):
self.mainForm.addGroupLabel(self.tr("Writing Guides")) self.mainForm.addGroupLabel(self.tr("Writing Guides"))
# Show Tabs and Spaces # Show Tabs and Spaces
self.showTabsNSpaces = QSwitch() self.showTabsNSpaces = NSwitch()
self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Show tabs and spaces"), self.tr("Show tabs and spaces"),
@@ -747,7 +749,7 @@ class GuiPreferencesEditor(QWidget):
) )
# Show Line Endings # Show Line Endings
self.showLineEndings = QSwitch() self.showLineEndings = NSwitch()
self.showLineEndings.setChecked(self.mainConf.showLineEndings) self.showLineEndings.setChecked(self.mainConf.showLineEndings)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Show line endings"), self.tr("Show line endings"),
@@ -772,7 +774,7 @@ class GuiPreferencesEditor(QWidget):
) )
# Typewriter Scrolling # Typewriter Scrolling
self.autoScroll = QSwitch() self.autoScroll = NSwitch()
self.autoScroll.setChecked(self.mainConf.autoScroll) self.autoScroll.setChecked(self.mainConf.autoScroll)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Typewriter style scrolling when you type"), self.tr("Typewriter style scrolling when you type"),
@@ -831,7 +833,7 @@ class GuiPreferencesSyntax(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -839,7 +841,7 @@ class GuiPreferencesSyntax(QWidget):
# ================= # =================
self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue")) self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue"))
self.highlightQuotes = QSwitch() self.highlightQuotes = NSwitch()
self.highlightQuotes.setChecked(self.mainConf.highlightQuotes) self.highlightQuotes.setChecked(self.mainConf.highlightQuotes)
self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes) self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes)
self.mainForm.addRow( self.mainForm.addRow(
@@ -848,7 +850,7 @@ class GuiPreferencesSyntax(QWidget):
self.tr("Applies to the document editor only.") self.tr("Applies to the document editor only.")
) )
self.allowOpenSQuote = QSwitch() self.allowOpenSQuote = NSwitch()
self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote) self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Allow open-ended single quotes"), 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.tr("Highlight single-quoted line with no closing quote.")
) )
self.allowOpenDQuote = QSwitch() self.allowOpenDQuote = NSwitch()
self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote) self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Allow open-ended double quotes"), self.tr("Allow open-ended double quotes"),
@@ -868,7 +870,7 @@ class GuiPreferencesSyntax(QWidget):
# ============= # =============
self.mainForm.addGroupLabel(self.tr("Text Emphasis")) self.mainForm.addGroupLabel(self.tr("Text Emphasis"))
self.highlightEmph = QSwitch() self.highlightEmph = NSwitch()
self.highlightEmph.setChecked(self.mainConf.highlightEmph) self.highlightEmph.setChecked(self.mainConf.highlightEmph)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Add highlight colour to emphasised text"), self.tr("Add highlight colour to emphasised text"),
@@ -881,7 +883,7 @@ class GuiPreferencesSyntax(QWidget):
self.mainForm.addGroupLabel(self.tr("Text Errors")) self.mainForm.addGroupLabel(self.tr("Text Errors"))
self.showMultiSpaces = QSwitch() self.showMultiSpaces = NSwitch()
self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces) self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Highlight multiple or trailing spaces"), self.tr("Highlight multiple or trailing spaces"),
@@ -937,7 +939,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -946,7 +948,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainForm.addGroupLabel(self.tr("Automatic Features")) self.mainForm.addGroupLabel(self.tr("Automatic Features"))
# Auto-Select Word Under Cursor # Auto-Select Word Under Cursor
self.autoSelect = QSwitch() self.autoSelect = NSwitch()
self.autoSelect.setChecked(self.mainConf.autoSelect) self.autoSelect.setChecked(self.mainConf.autoSelect)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Auto-select word under cursor"), self.tr("Auto-select word under cursor"),
@@ -955,7 +957,7 @@ class GuiPreferencesAutomation(QWidget):
) )
# Auto-Replace as You Type Main Switch # Auto-Replace as You Type Main Switch
self.doReplace = QSwitch() self.doReplace = NSwitch()
self.doReplace.setChecked(self.mainConf.doReplace) self.doReplace.setChecked(self.mainConf.doReplace)
self.doReplace.toggled.connect(self._toggleAutoReplaceMain) self.doReplace.toggled.connect(self._toggleAutoReplaceMain)
self.mainForm.addRow( self.mainForm.addRow(
@@ -969,7 +971,7 @@ class GuiPreferencesAutomation(QWidget):
self.mainForm.addGroupLabel(self.tr("Replace as You Type")) self.mainForm.addGroupLabel(self.tr("Replace as You Type"))
# Auto-Replace Single Quotes # Auto-Replace Single Quotes
self.doReplaceSQuote = QSwitch() self.doReplaceSQuote = NSwitch()
self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote) self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote)
self.doReplaceSQuote.setEnabled(self.mainConf.doReplace) self.doReplaceSQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow( self.mainForm.addRow(
@@ -979,7 +981,7 @@ class GuiPreferencesAutomation(QWidget):
) )
# Auto-Replace Double Quotes # Auto-Replace Double Quotes
self.doReplaceDQuote = QSwitch() self.doReplaceDQuote = NSwitch()
self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote) self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote)
self.doReplaceDQuote.setEnabled(self.mainConf.doReplace) self.doReplaceDQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow( self.mainForm.addRow(
@@ -989,7 +991,7 @@ class GuiPreferencesAutomation(QWidget):
) )
# Auto-Replace Hyphens # Auto-Replace Hyphens
self.doReplaceDash = QSwitch() self.doReplaceDash = NSwitch()
self.doReplaceDash.setChecked(self.mainConf.doReplaceDash) self.doReplaceDash.setChecked(self.mainConf.doReplaceDash)
self.doReplaceDash.setEnabled(self.mainConf.doReplace) self.doReplaceDash.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow( self.mainForm.addRow(
@@ -999,7 +1001,7 @@ class GuiPreferencesAutomation(QWidget):
) )
# Auto-Replace Dots # Auto-Replace Dots
self.doReplaceDots = QSwitch() self.doReplaceDots = NSwitch()
self.doReplaceDots.setChecked(self.mainConf.doReplaceDots) self.doReplaceDots.setChecked(self.mainConf.doReplaceDots)
self.doReplaceDots.setEnabled(self.mainConf.doReplace) self.doReplaceDots.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow( self.mainForm.addRow(
@@ -1033,7 +1035,7 @@ class GuiPreferencesAutomation(QWidget):
) )
# Use Thin Space # Use Thin Space
self.fmtPadThin = QSwitch() self.fmtPadThin = NSwitch()
self.fmtPadThin.setChecked(self.mainConf.fmtPadThin) self.fmtPadThin.setChecked(self.mainConf.fmtPadThin)
self.fmtPadThin.setEnabled(self.mainConf.doReplace) self.fmtPadThin.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow( self.mainForm.addRow(
@@ -1092,7 +1094,7 @@ class GuiPreferencesQuotes(QWidget):
self.mainTheme = prefsGui.mainGui.mainTheme self.mainTheme = prefsGui.mainGui.mainTheme
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
+4 -3
View File
@@ -35,14 +35,15 @@ from PyQt5.QtWidgets import (
) )
from novelwriter.common import formatTime, numberToRoman from novelwriter.common import formatTime, numberToRoman
from novelwriter.custom import PagedDialog, QSwitch
from novelwriter.constants import nwUnicode from novelwriter.constants import nwUnicode
from novelwriter.custom.switch import NSwitch
from novelwriter.custom.pageddialog import NPagedDialog
from novelwriter.gui.components import NovelSelector from novelwriter.gui.components import NovelSelector
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiProjectDetails(PagedDialog): class GuiProjectDetails(NPagedDialog):
def __init__(self, mainGui): def __init__(self, mainGui):
super().__init__(parent=mainGui) super().__init__(parent=mainGui)
@@ -386,7 +387,7 @@ class GuiProjectDetailsContents(QWidget):
self.dblLabel = QLabel(self.tr("Clear double pages")) self.dblLabel = QLabel(self.tr("Clear double pages"))
self.dblLabel.setToolTip(dblHelp) self.dblLabel.setToolTip(dblHelp)
self.dblValue = QSwitch(self, 2*iPx, iPx) self.dblValue = NSwitch(self, 2*iPx, iPx)
self.dblValue.setChecked(clearDouble) self.dblValue.setChecked(clearDouble)
self.dblValue.setToolTip(dblHelp) self.dblValue.setToolTip(dblHelp)
self.dblValue.clicked.connect(self._populateTree) self.dblValue.clicked.connect(self._populateTree)
+6 -4
View File
@@ -35,12 +35,14 @@ from PyQt5.QtWidgets import (
from novelwriter.enum import nwAlert from novelwriter.enum import nwAlert
from novelwriter.common import simplified 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__) logger = logging.getLogger(__name__)
class GuiProjectSettings(PagedDialog): class GuiProjectSettings(NPagedDialog):
TAB_MAIN = 0 TAB_MAIN = 0
TAB_STATUS = 1 TAB_STATUS = 1
@@ -196,7 +198,7 @@ class GuiProjectEditMain(QWidget):
self.theProject = projGui.theProject self.theProject = projGui.theProject
# The Form # The Form
self.mainForm = QConfigLayout() self.mainForm = NConfigLayout()
self.mainForm.setHelpTextStyle(self.mainGui.mainTheme.helpText) self.mainForm.setHelpTextStyle(self.mainGui.mainTheme.helpText)
self.setLayout(self.mainForm) self.setLayout(self.mainForm)
@@ -255,7 +257,7 @@ class GuiProjectEditMain(QWidget):
if spellIdx != -1: if spellIdx != -1:
self.spellLang.setCurrentIndex(spellIdx) self.spellLang.setCurrentIndex(spellIdx)
self.doBackup = QSwitch(self) self.doBackup = NSwitch(self)
self.doBackup.setChecked(not self.theProject.data.doBackup) self.doBackup.setChecked(not self.theProject.data.doBackup)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("No backup on close"), self.tr("No backup on close"),
+1 -1
View File
@@ -1,6 +1,6 @@
""" """
novelWriter GUI Main Window SideBar novelWriter GUI Main Window SideBar
=========================================== =====================================
GUI class for the main window side bar GUI class for the main window side bar
File History: File History:
+15 -15
View File
@@ -46,11 +46,11 @@ from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from novelwriter.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass from novelwriter.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass
from novelwriter.error import formatException, logException from novelwriter.error import formatException, logException
from novelwriter.common import fuzzyTime, makeFileNameSafe from novelwriter.common import fuzzyTime, makeFileNameSafe
from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles from novelwriter.constants import nwConst, nwFiles
from novelwriter.core.tomd import ToMarkdown from novelwriter.core.tomd import ToMarkdown
from novelwriter.core.toodt import ToOdt from novelwriter.core.toodt import ToOdt
from novelwriter.core.tohtml import ToHtml from novelwriter.core.tohtml import ToHtml
from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -174,12 +174,12 @@ class GuiBuildNovel(QDialog):
if langIdx != -1: if langIdx != -1:
self.buildLang.setCurrentIndex(langIdx) self.buildLang.setCurrentIndex(langIdx)
self.hideScene = QSwitch(width=wS, height=hS) self.hideScene = NSwitch(width=wS, height=hS)
self.hideScene.setChecked( self.hideScene.setChecked(
pOptions.getBool("GuiBuildNovel", "hideScene", False) pOptions.getBool("GuiBuildNovel", "hideScene", False)
) )
self.hideSection = QSwitch(width=wS, height=hS) self.hideSection = NSwitch(width=wS, height=hS)
self.hideSection.setChecked( self.hideSection.setChecked(
pOptions.getBool("GuiBuildNovel", "hideSection", True) pOptions.getBool("GuiBuildNovel", "hideSection", True)
) )
@@ -291,12 +291,12 @@ class GuiBuildNovel(QDialog):
self.styleForm = QGridLayout(self) self.styleForm = QGridLayout(self)
self.styleGroup.setLayout(self.styleForm) self.styleGroup.setLayout(self.styleForm)
self.justifyText = QSwitch(width=wS, height=hS) self.justifyText = NSwitch(width=wS, height=hS)
self.justifyText.setChecked( self.justifyText.setChecked(
pOptions.getBool("GuiBuildNovel", "justifyText", False) pOptions.getBool("GuiBuildNovel", "justifyText", False)
) )
self.noStyling = QSwitch(width=wS, height=hS) self.noStyling = NSwitch(width=wS, height=hS)
self.noStyling.setChecked( self.noStyling.setChecked(
pOptions.getBool("GuiBuildNovel", "noStyling", False) pOptions.getBool("GuiBuildNovel", "noStyling", False)
) )
@@ -316,22 +316,22 @@ class GuiBuildNovel(QDialog):
self.textForm = QGridLayout(self) self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm) self.textGroup.setLayout(self.textForm)
self.includeSynopsis = QSwitch(width=wS, height=hS) self.includeSynopsis = NSwitch(width=wS, height=hS)
self.includeSynopsis.setChecked( self.includeSynopsis.setChecked(
pOptions.getBool("GuiBuildNovel", "incSynopsis", False) pOptions.getBool("GuiBuildNovel", "incSynopsis", False)
) )
self.includeComments = QSwitch(width=wS, height=hS) self.includeComments = NSwitch(width=wS, height=hS)
self.includeComments.setChecked( self.includeComments.setChecked(
pOptions.getBool("GuiBuildNovel", "incComments", False) pOptions.getBool("GuiBuildNovel", "incComments", False)
) )
self.includeKeywords = QSwitch(width=wS, height=hS) self.includeKeywords = NSwitch(width=wS, height=hS)
self.includeKeywords.setChecked( self.includeKeywords.setChecked(
pOptions.getBool("GuiBuildNovel", "incKeywords", False) pOptions.getBool("GuiBuildNovel", "incKeywords", False)
) )
self.includeBody = QSwitch(width=wS, height=hS) self.includeBody = NSwitch(width=wS, height=hS)
self.includeBody.setChecked( self.includeBody.setChecked(
pOptions.getBool("GuiBuildNovel", "incBodyText", True) pOptions.getBool("GuiBuildNovel", "incBodyText", True)
) )
@@ -371,7 +371,7 @@ class GuiBuildNovel(QDialog):
rootLabel = QLabel(nwItem.itemName) rootLabel = QLabel(nwItem.itemName)
rootLabel.setWordWrap(True) rootLabel.setWordWrap(True)
rootValue = QSwitch(width=wS, height=hS) rootValue = NSwitch(width=wS, height=hS)
rootValue.setChecked(tHandle not in rootFilter) rootValue.setChecked(tHandle not in rootFilter)
self.rootSelection[tHandle] = rootValue self.rootSelection[tHandle] = rootValue
@@ -390,17 +390,17 @@ class GuiBuildNovel(QDialog):
self.fileForm = QGridLayout(self) self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm) self.fileGroup.setLayout(self.fileForm)
self.novelFiles = QSwitch(width=wS, height=hS) self.novelFiles = NSwitch(width=wS, height=hS)
self.novelFiles.setChecked( self.novelFiles.setChecked(
pOptions.getBool("GuiBuildNovel", "addNovel", True) pOptions.getBool("GuiBuildNovel", "addNovel", True)
) )
self.noteFiles = QSwitch(width=wS, height=hS) self.noteFiles = NSwitch(width=wS, height=hS)
self.noteFiles.setChecked( self.noteFiles.setChecked(
pOptions.getBool("GuiBuildNovel", "addNotes", False) pOptions.getBool("GuiBuildNovel", "addNotes", False)
) )
self.ignoreFlag = QSwitch(width=wS, height=hS) self.ignoreFlag = NSwitch(width=wS, height=hS)
self.ignoreFlag.setChecked( self.ignoreFlag.setChecked(
pOptions.getBool("GuiBuildNovel", "ignoreFlag", False) pOptions.getBool("GuiBuildNovel", "ignoreFlag", False)
) )
@@ -426,12 +426,12 @@ class GuiBuildNovel(QDialog):
self.exportForm = QGridLayout(self) self.exportForm = QGridLayout(self)
self.exportGroup.setLayout(self.exportForm) self.exportGroup.setLayout(self.exportForm)
self.replaceTabs = QSwitch(width=wS, height=hS) self.replaceTabs = NSwitch(width=wS, height=hS)
self.replaceTabs.setChecked( self.replaceTabs.setChecked(
pOptions.getBool("GuiBuildNovel", "replaceTabs", False) pOptions.getBool("GuiBuildNovel", "replaceTabs", False)
) )
self.replaceUCode = QSwitch(width=wS, height=hS) self.replaceUCode = NSwitch(width=wS, height=hS)
self.replaceUCode.setChecked( self.replaceUCode.setChecked(
pOptions.getBool("GuiBuildNovel", "replaceUCode", False) pOptions.getBool("GuiBuildNovel", "replaceUCode", False)
) )
+2 -2
View File
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
) )
from novelwriter.common import readTextFile from novelwriter.common import readTextFile
from novelwriter.custom import QSwitch from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -78,7 +78,7 @@ class GuiLipsum(QDialog):
self.paraCount.setValue(5) self.paraCount.setValue(5)
self.randLabel = QLabel(self.tr("Randomise order")) self.randLabel = QLabel(self.tr("Randomise order"))
self.randSwitch = QSwitch() self.randSwitch = NSwitch()
self.formBox = QGridLayout() self.formBox = QGridLayout()
self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignLeft) self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignLeft)
+5 -5
View File
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
) )
from novelwriter.common import makeFileNameSafe from novelwriter.common import makeFileNameSafe
from novelwriter.custom import QSwitch from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -328,19 +328,19 @@ class ProjWizardCustomPage(QWizardPage):
fS = self.mainConf.pxInt(4) fS = self.mainConf.pxInt(4)
# Root Folders # Root Folders
self.addPlot = QSwitch() self.addPlot = NSwitch()
self.addPlot.setChecked(True) self.addPlot.setChecked(True)
self.addPlot.clicked.connect(self._syncSwitches) self.addPlot.clicked.connect(self._syncSwitches)
self.addChar = QSwitch() self.addChar = NSwitch()
self.addChar.setChecked(True) self.addChar.setChecked(True)
self.addChar.clicked.connect(self._syncSwitches) self.addChar.clicked.connect(self._syncSwitches)
self.addWorld = QSwitch() self.addWorld = NSwitch()
self.addWorld.setChecked(False) self.addWorld.setChecked(False)
self.addWorld.clicked.connect(self._syncSwitches) self.addWorld.clicked.connect(self._syncSwitches)
self.addNotes = QSwitch() self.addNotes = NSwitch()
self.addNotes.setChecked(False) self.addNotes.setChecked(False)
# Generate Content # Generate Content
+7 -7
View File
@@ -40,8 +40,8 @@ from PyQt5.QtWidgets import (
from novelwriter.enum import nwAlert from novelwriter.enum import nwAlert
from novelwriter.error import formatException from novelwriter.error import formatException
from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax
from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles from novelwriter.constants import nwConst, nwFiles
from novelwriter.custom.switch import NSwitch
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -190,37 +190,37 @@ class GuiWritingStats(QDialog):
self.filterForm = QGridLayout(self) self.filterForm = QGridLayout(self)
self.filterBox.setLayout(self.filterForm) self.filterBox.setLayout(self.filterForm)
self.incNovel = QSwitch(width=2*sPx, height=sPx) self.incNovel = NSwitch(width=2*sPx, height=sPx)
self.incNovel.setChecked( self.incNovel.setChecked(
pOptions.getBool("GuiWritingStats", "incNovel", True) pOptions.getBool("GuiWritingStats", "incNovel", True)
) )
self.incNovel.clicked.connect(self._updateListBox) 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( self.incNotes.setChecked(
pOptions.getBool("GuiWritingStats", "incNotes", True) pOptions.getBool("GuiWritingStats", "incNotes", True)
) )
self.incNotes.clicked.connect(self._updateListBox) 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( self.hideZeros.setChecked(
pOptions.getBool("GuiWritingStats", "hideZeros", True) pOptions.getBool("GuiWritingStats", "hideZeros", True)
) )
self.hideZeros.clicked.connect(self._updateListBox) 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( self.hideNegative.setChecked(
pOptions.getBool("GuiWritingStats", "hideNegative", False) pOptions.getBool("GuiWritingStats", "hideNegative", False)
) )
self.hideNegative.clicked.connect(self._updateListBox) 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( self.groupByDay.setChecked(
pOptions.getBool("GuiWritingStats", "groupByDay", False) pOptions.getBool("GuiWritingStats", "groupByDay", False)
) )
self.groupByDay.clicked.connect(self._updateListBox) 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( self.showIdleTime.setChecked(
pOptions.getBool("GuiWritingStats", "showIdleTime", False) pOptions.getBool("GuiWritingStats", "showIdleTime", False)
) )