From e088b03c047d3d0339b2f37bb8240b2ec52327e1 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 12:04:36 +0200 Subject: [PATCH 01/10] Added original switch code from stack overflow --- nw/additions/qswitch.py | 223 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 nw/additions/qswitch.py diff --git a/nw/additions/qswitch.py b/nw/additions/qswitch.py new file mode 100644 index 00000000..b7d3fdcd --- /dev/null +++ b/nw/additions/qswitch.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- +"""novelWriter Addition QSwitch + + novelWriter – Addition QSwitch +================================ + A custom Qt switch button + + File History: + Created: 2020-05-03 [0.4.5] + + This class is based on Stack Overflow code by Stefan Scherfke, based + again on contribution by IMAN4K, published under license CC BY-SA 4.0. + https://stackoverflow.com/a/51825815/5825851 + + The above code has been modified to integrate with novelWriter, and + re-released under compatible GPLv3 (see creativecommons.org). + + This file is a part of novelWriter + Copyright 2020, 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 nw + +from PyQt5.QtCore import QPropertyAnimation, QRectF, QSize, Qt, pyqtProperty +from PyQt5.QtGui import QPainter +from PyQt5.QtWidgets import ( + QAbstractButton, + QApplication, + QHBoxLayout, + QSizePolicy, + QWidget, +) + +logger = logging.getLogger(__name__) + +class Switch(QAbstractButton): + def __init__(self, parent=None, track_radius=10, thumb_radius=8): + super().__init__(parent=parent) + self.setCheckable(True) + self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + + self._track_radius = track_radius + self._thumb_radius = thumb_radius + + self._margin = max(0, self._thumb_radius - self._track_radius) + self._base_offset = max(self._thumb_radius, self._track_radius) + self._end_offset = { + True: lambda: self.width() - self._base_offset, + False: lambda: self._base_offset, + } + self._offset = self._base_offset + + palette = self.palette() + if self._thumb_radius > self._track_radius: + self._track_color = { + True: palette.highlight(), + False: palette.dark(), + } + self._thumb_color = { + True: palette.highlight(), + False: palette.light(), + } + self._text_color = { + True: palette.highlightedText().color(), + False: palette.dark().color(), + } + self._thumb_text = { + True: '', + False: '', + } + self._track_opacity = 0.5 + else: + self._thumb_color = { + True: palette.highlightedText(), + False: palette.light(), + } + self._track_color = { + True: palette.highlight(), + False: palette.dark(), + } + self._text_color = { + True: palette.highlight().color(), + False: palette.dark().color(), + } + self._thumb_text = { + True: '✔', + False: '✕', + } + self._track_opacity = 1 + + @pyqtProperty(int) + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + self.update() + + def sizeHint(self): # pylint: disable=invalid-name + return QSize( + 4 * self._track_radius + 2 * self._margin, + 2 * self._track_radius + 2 * self._margin, + ) + + def setChecked(self, checked): + super().setChecked(checked) + self.offset = self._end_offset[checked]() + + def resizeEvent(self, event): + super().resizeEvent(event) + self.offset = self._end_offset[self.isChecked()]() + + def paintEvent(self, event): # pylint: disable=invalid-name, unused-argument + p = QPainter(self) + p.setRenderHint(QPainter.Antialiasing, True) + p.setPen(Qt.NoPen) + track_opacity = self._track_opacity + thumb_opacity = 1.0 + text_opacity = 1.0 + if self.isEnabled(): + track_brush = self._track_color[self.isChecked()] + thumb_brush = self._thumb_color[self.isChecked()] + text_color = self._text_color[self.isChecked()] + else: + track_opacity *= 0.8 + track_brush = self.palette().shadow() + thumb_brush = self.palette().mid() + text_color = self.palette().shadow().color() + + p.setBrush(track_brush) + p.setOpacity(track_opacity) + p.drawRoundedRect( + self._margin, + self._margin, + self.width() - 2 * self._margin, + self.height() - 2 * self._margin, + self._track_radius, + self._track_radius, + ) + p.setBrush(thumb_brush) + p.setOpacity(thumb_opacity) + p.drawEllipse( + self.offset - self._thumb_radius, + self._base_offset - self._thumb_radius, + 2 * self._thumb_radius, + 2 * self._thumb_radius, + ) + p.setPen(text_color) + p.setOpacity(text_opacity) + font = p.font() + font.setPixelSize(1.5 * self._thumb_radius) + p.setFont(font) + p.drawText( + QRectF( + self.offset - self._thumb_radius, + self._base_offset - self._thumb_radius, + 2 * self._thumb_radius, + 2 * self._thumb_radius, + ), + Qt.AlignCenter, + self._thumb_text[self.isChecked()], + ) + + def mouseReleaseEvent(self, event): # pylint: disable=invalid-name + super().mouseReleaseEvent(event) + if event.button() == Qt.LeftButton: + anim = QPropertyAnimation(self, b'offset', self) + anim.setDuration(120) + anim.setStartValue(self.offset) + anim.setEndValue(self._end_offset[self.isChecked()]()) + anim.start() + + def enterEvent(self, event): # pylint: disable=invalid-name + self.setCursor(Qt.PointingHandCursor) + super().enterEvent(event) + + +# def main(): +# app = QApplication([]) + +# # Thumb size < track size (Gitlab style) +# s1 = Switch() +# s1.toggled.connect(lambda c: print('toggled', c)) +# s1.clicked.connect(lambda c: print('clicked', c)) +# s1.pressed.connect(lambda: print('pressed')) +# s1.released.connect(lambda: print('released')) +# s2 = Switch() +# s2.setEnabled(False) + +# # Thumb size > track size (Android style) +# s3 = Switch(thumb_radius=11, track_radius=8) +# s4 = Switch(thumb_radius=11, track_radius=8) +# s4.setEnabled(False) + +# l = QHBoxLayout() +# l.addWidget(s1) +# l.addWidget(s2) +# l.addWidget(s3) +# l.addWidget(s4) +# w = QWidget() +# w.setLayout(l) +# w.show() + +# app.exec() + + +# if __name__ == '__main__': +# main() From 1fe9ff0af78a7a91c67997373a3b86946de5cff1 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 12:45:58 +0200 Subject: [PATCH 02/10] Updated the switch class to match code standard --- nw/additions/qswitch.py | 248 ++++++++++++++++++++------------------ nw/constants/constants.py | 4 + 2 files changed, 136 insertions(+), 116 deletions(-) diff --git a/nw/additions/qswitch.py b/nw/additions/qswitch.py index b7d3fdcd..b25e99eb 100644 --- a/nw/additions/qswitch.py +++ b/nw/additions/qswitch.py @@ -35,72 +35,74 @@ import logging import nw -from PyQt5.QtCore import QPropertyAnimation, QRectF, QSize, Qt, pyqtProperty +from PyQt5.QtCore import Qt, QSize, QRectF, QPropertyAnimation, pyqtProperty +from PyQt5.QtWidgets import QAbstractButton, QSizePolicy from PyQt5.QtGui import QPainter -from PyQt5.QtWidgets import ( - QAbstractButton, - QApplication, - QHBoxLayout, - QSizePolicy, - QWidget, -) + +from nw.constants import nwUnicode logger = logging.getLogger(__name__) -class Switch(QAbstractButton): - def __init__(self, parent=None, track_radius=10, thumb_radius=8): +class QSwitch(QAbstractButton): + + def __init__(self, parent=None): super().__init__(parent=parent) + self.setCheckable(True) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) - self._track_radius = track_radius - self._thumb_radius = thumb_radius + self._trackRadius = 10 + self._thumbRadius = 8 - self._margin = max(0, self._thumb_radius - self._track_radius) - self._base_offset = max(self._thumb_radius, self._track_radius) - self._end_offset = { - True: lambda: self.width() - self._base_offset, - False: lambda: self._base_offset, + self._margin = max(0, self._thumbRadius - self._trackRadius) + self._baseOffset = max(self._thumbRadius, self._trackRadius) + self._endOffset = { + True: lambda: self.width() - self._baseOffset, + False: lambda: self._baseOffset, } - self._offset = self._base_offset + self._offset = self._baseOffset palette = self.palette() - if self._thumb_radius > self._track_radius: - self._track_color = { + if self._thumbRadius > self._trackRadius: + self._trackColor = { True: palette.highlight(), False: palette.dark(), } - self._thumb_color = { + self._thumbColor = { True: palette.highlight(), False: palette.light(), } - self._text_color = { + self._textColor = { True: palette.highlightedText().color(), False: palette.dark().color(), } - self._thumb_text = { + self._thumbText = { True: '', False: '', } - self._track_opacity = 0.5 + self._trackOpacity = 0.5 else: - self._thumb_color = { + self._thumbColor = { True: palette.highlightedText(), False: palette.light(), } - self._track_color = { + self._trackColor = { True: palette.highlight(), False: palette.dark(), } - self._text_color = { + self._textColor = { True: palette.highlight().color(), False: palette.dark().color(), } - self._thumb_text = { - True: '✔', - False: '✕', + self._thumbText = { + True: nwUnicode.U_CHECK, + False: nwUnicode.U_MULT, } - self._track_opacity = 1 + self._trackOpacity = 1 + + ## + # Properties + ## @pyqtProperty(int) def offset(self): @@ -110,114 +112,128 @@ class Switch(QAbstractButton): def offset(self, value): self._offset = value self.update() + return - def sizeHint(self): # pylint: disable=invalid-name - return QSize( - 4 * self._track_radius + 2 * self._margin, - 2 * self._track_radius + 2 * self._margin, - ) + ## + # Getters and Setters + ## + + def trackRadius(self): + return self._trackRadius + + def setTrackRadius(self, theValue): + if isinstance(theValue, int): + if theValue > 0: + self._trackRadius = theValue + return + raise ValueError("trackRadius must be an integer > 0") + self.update() + return + + def thumbRadius(self): + return self._thumbRadius + + def setThumbRadius(self, theValue): + if isinstance(theValue, int): + if theValue > 0: + self._thumbRadius = theValue + return + raise ValueError("thumbRadius must be an integer > 0") + self.update() + return def setChecked(self, checked): super().setChecked(checked) - self.offset = self._end_offset[checked]() + self.offset = self._endOffset[checked]() + + def sizeHint(self): + return QSize( + 4 * self._trackRadius + 2 * self._margin, + 2 * self._trackRadius + 2 * self._margin, + ) + + ## + # Events + ## def resizeEvent(self, event): + """Overload resize to ensure correct offset. + """ super().resizeEvent(event) - self.offset = self._end_offset[self.isChecked()]() + self.offset = self._endOffset[self.isChecked()]() + return - def paintEvent(self, event): # pylint: disable=invalid-name, unused-argument - p = QPainter(self) - p.setRenderHint(QPainter.Antialiasing, True) - p.setPen(Qt.NoPen) - track_opacity = self._track_opacity - thumb_opacity = 1.0 - text_opacity = 1.0 + def paintEvent(self, event): + """Drawing the switch itself. + """ + qPaint = QPainter(self) + qPaint.setRenderHint(QPainter.Antialiasing, True) + qPaint.setPen(Qt.NoPen) + trackOpacity = self._trackOpacity + thumbOpacity = 1.0 + textOpacity = 1.0 if self.isEnabled(): - track_brush = self._track_color[self.isChecked()] - thumb_brush = self._thumb_color[self.isChecked()] - text_color = self._text_color[self.isChecked()] + trackBrush = self._trackColor[self.isChecked()] + thumbBrush = self._thumbColor[self.isChecked()] + textColor = self._textColor[self.isChecked()] else: - track_opacity *= 0.8 - track_brush = self.palette().shadow() - thumb_brush = self.palette().mid() - text_color = self.palette().shadow().color() + trackOpacity *= 0.8 + trackBrush = self.palette().shadow() + thumbBrush = self.palette().mid() + textColor = self.palette().shadow().color() - p.setBrush(track_brush) - p.setOpacity(track_opacity) - p.drawRoundedRect( + qPaint.setBrush(trackBrush) + qPaint.setOpacity(trackOpacity) + qPaint.drawRoundedRect( self._margin, self._margin, - self.width() - 2 * self._margin, - self.height() - 2 * self._margin, - self._track_radius, - self._track_radius, + self.width() - 2*self._margin, + self.height() - 2*self._margin, + self._trackRadius, + self._trackRadius, ) - p.setBrush(thumb_brush) - p.setOpacity(thumb_opacity) - p.drawEllipse( - self.offset - self._thumb_radius, - self._base_offset - self._thumb_radius, - 2 * self._thumb_radius, - 2 * self._thumb_radius, + qPaint.setBrush(thumbBrush) + qPaint.setOpacity(thumbOpacity) + qPaint.drawEllipse( + self.offset - self._thumbRadius, + self._baseOffset - self._thumbRadius, + 2*self._thumbRadius, + 2*self._thumbRadius, ) - p.setPen(text_color) - p.setOpacity(text_opacity) - font = p.font() - font.setPixelSize(1.5 * self._thumb_radius) - p.setFont(font) - p.drawText( + qPaint.setPen(textColor) + qPaint.setOpacity(textOpacity) + theFont = qPaint.font() + theFont.setPixelSize(1.5*self._thumbRadius) + qPaint.setFont(theFont) + qPaint.drawText( QRectF( - self.offset - self._thumb_radius, - self._base_offset - self._thumb_radius, - 2 * self._thumb_radius, - 2 * self._thumb_radius, + self.offset - self._thumbRadius, + self._baseOffset - self._thumbRadius, + 2*self._thumbRadius, + 2*self._thumbRadius, ), Qt.AlignCenter, - self._thumb_text[self.isChecked()], + self._thumbText[self.isChecked()], ) + return - def mouseReleaseEvent(self, event): # pylint: disable=invalid-name + def mouseReleaseEvent(self, event): + """Animate the switch. + """ super().mouseReleaseEvent(event) if event.button() == Qt.LeftButton: - anim = QPropertyAnimation(self, b'offset', self) - anim.setDuration(120) - anim.setStartValue(self.offset) - anim.setEndValue(self._end_offset[self.isChecked()]()) - anim.start() + doAnim = QPropertyAnimation(self, b'offset', self) + doAnim.setDuration(120) + doAnim.setStartValue(self.offset) + doAnim.setEndValue(self._endOffset[self.isChecked()]()) + doAnim.start() + return - def enterEvent(self, event): # pylint: disable=invalid-name + def enterEvent(self, event): + """Change the cursor when hovering the button. + """ self.setCursor(Qt.PointingHandCursor) super().enterEvent(event) + return - -# def main(): -# app = QApplication([]) - -# # Thumb size < track size (Gitlab style) -# s1 = Switch() -# s1.toggled.connect(lambda c: print('toggled', c)) -# s1.clicked.connect(lambda c: print('clicked', c)) -# s1.pressed.connect(lambda: print('pressed')) -# s1.released.connect(lambda: print('released')) -# s2 = Switch() -# s2.setEnabled(False) - -# # Thumb size > track size (Android style) -# s3 = Switch(thumb_radius=11, track_radius=8) -# s4 = Switch(thumb_radius=11, track_radius=8) -# s4.setEnabled(False) - -# l = QHBoxLayout() -# l.addWidget(s1) -# l.addWidget(s2) -# l.addWidget(s3) -# l.addWidget(s4) -# w = QWidget() -# w.setLayout(l) -# w.show() - -# app.exec() - - -# if __name__ == '__main__': -# main() +# END Class QSwitch diff --git a/nw/constants/constants.py b/nw/constants/constants.py index 3f6192d4..fe327525 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -233,6 +233,8 @@ class nwUnicode: ## Other U_NBSP = "\u00a0" # Non-breaking space U_PARA = "\u2029" # Paragraph separator + U_CHECK = "\u2714" # Heavy check mark + U_MULT = "\u2715" # Multiplication x ## Arrows U_UTRI = "\u2bc5" # Up-pointing triangle @@ -270,6 +272,8 @@ class nwUnicode: ## Other H_NBSP = " " + H_CHECK = "✔" + H_MULT = "✕" ## Arrows H_UTRI = "⯅" From bf9e365d259e9e5eabed219ec3943d30603d1508 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 16:55:24 +0200 Subject: [PATCH 03/10] Added a custom class for forms --- nw/additions/__init__.py | 8 ++ nw/additions/qconfiglayout.py | 178 ++++++++++++++++++++++++++++++++++ nw/additions/qswitch.py | 4 +- 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 nw/additions/__init__.py create mode 100644 nw/additions/qconfiglayout.py diff --git a/nw/additions/__init__.py b/nw/additions/__init__.py new file mode 100644 index 00000000..213df1b1 --- /dev/null +++ b/nw/additions/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +from nw.additions.qconfiglayout import QConfigLayout +from nw.additions.qswitch import QSwitch + +__all__ = [ + "QConfigLayout", + "QSwitch", +] diff --git a/nw/additions/qconfiglayout.py b/nw/additions/qconfiglayout.py new file mode 100644 index 00000000..431c9825 --- /dev/null +++ b/nw/additions/qconfiglayout.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +"""novelWriter Addition QConfigLayout + + novelWriter – Addition QConfigLayout +====================================== + A custom Qt grid layout for config forms similar to QFormLayout + + File History: + Created: 2020-05-03 [0.4.5] + + This file is a part of novelWriter + Copyright 2020, 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 nw + +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QColor, QPalette +from PyQt5.QtWidgets import ( + QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QLayout +) + +from nw.constants import nwUnicode + +logger = logging.getLogger(__name__) + +class QConfigLayout(QGridLayout): + + def __init__(self): + super().__init__() + + self._nextRow = 0 + self._helpCol = QColor(0, 0, 0) + self._fontScale = 0.9 + + self._itemMap = {} + + self.setHorizontalSpacing(8) + self.setVerticalSpacing(8) + + 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): + if intRow in self._itemMap: + self._itemMap[intRow]["help"].setText(theText) + return + + def setLabelText(self, intRow, theText): + 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(theLabel) + else: + qLabel = None + raise ValueError("theLabel must be a QLabel") + + qLabel.setContentsMargins(0,4,0,4) + 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): + """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") + + qLabel.setIndent(8) + if helpText is not None: + qHelp = QLabel(str(helpText)) + qHelp.setIndent(8) + + lblCol = qHelp.palette() + lblCol.setColor(QPalette.WindowText, self._helpCol) + qHelp.setPalette(lblCol) + + lblFont = qHelp.font() + lblFont.setPointSizeF(self._fontScale*lblFont.pointSizeF()) + qHelp.setFont(lblFont) + + labelBox = QVBoxLayout() + labelBox.addWidget(qLabel) + labelBox.addWidget(qHelp) + labelBox.setSpacing(0) + + thisEntry["help"] = qHelp + self.addLayout(labelBox, self._nextRow, 0, Qt.AlignLeft) + + else: + self.addWidget(qLabel, self._nextRow, 0, Qt.AlignLeft) + + if theUnit is not None: + controlBox = QHBoxLayout() + controlBox.addWidget(qWidget, 0, Qt.AlignVCenter) + controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter) + controlBox.setSpacing(8) + self.addLayout(controlBox, self._nextRow, 1, Qt.AlignRight) + else: + self.addWidget(qWidget, self._nextRow, 1, Qt.AlignRight) + + 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 diff --git a/nw/additions/qswitch.py b/nw/additions/qswitch.py index b25e99eb..f5db98ff 100644 --- a/nw/additions/qswitch.py +++ b/nw/additions/qswitch.py @@ -98,7 +98,9 @@ class QSwitch(QAbstractButton): True: nwUnicode.U_CHECK, False: nwUnicode.U_MULT, } - self._trackOpacity = 1 + self._trackOpacity = 1.0 + + return ## # Properties From 3d0cd5a71c834746197db80eb339216c90ee3a8c Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 16:56:03 +0200 Subject: [PATCH 04/10] Move a bunch of settings to a new tab in main settings using the new config layout --- nw/gui/dialogs/configeditor.py | 309 +++++++++++++++++++-------------- nw/gui/theme.py | 17 ++ 2 files changed, 200 insertions(+), 126 deletions(-) diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index da26593f..cd85f10e 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -35,9 +35,10 @@ from PyQt5.QtGui import QFont from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QVBoxLayout, QLineEdit, QLabel, QWidget, QTabWidget, QDialogButtonBox, QSpinBox, QGroupBox, QComboBox, QMessageBox, QCheckBox, - QGridLayout, QFontComboBox, QPushButton, QFileDialog + QGridLayout, QFontComboBox, QPushButton, QFileDialog, QFormLayout ) +from nw.additions import QSwitch, QConfigLayout from nw.tools import NWSpellCheck, NWSpellSimple, NWSpellEnchant from nw.constants import nwAlert, nwQuotes @@ -59,10 +60,13 @@ class GuiConfigEditor(QDialog): self.setWindowTitle("Preferences") self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64)) + self.tabGeneral = GuiConfigEditGeneralTab(self.theParent) self.tabMain = GuiConfigEditGeneral(self.theParent) self.tabEditor = GuiConfigEditEditor(self.theParent) self.tabWidget = QTabWidget() + self.tabWidget.setMinimumWidth(600) + self.tabWidget.addTab(self.tabGeneral, "General") self.tabWidget.addTab(self.tabMain, "General") self.tabWidget.addTab(self.tabEditor, "Editor") @@ -94,6 +98,10 @@ class GuiConfigEditor(QDialog): validEntries = True needsRestart = False + retA, retB = self.tabGeneral.saveValues() + validEntries &= retA + needsRestart |= retB + retA, retB = self.tabMain.saveValues() validEntries &= retA needsRestart |= retB @@ -121,6 +129,180 @@ class GuiConfigEditor(QDialog): # END Class GuiConfigEditor +class GuiConfigEditGeneralTab(QWidget): + + def __init__(self, theParent): + QWidget.__init__(self, theParent) + + self.mainConf = nw.CONFIG + self.theParent = theParent + self.theTheme = theParent.theTheme + + # The Form + self.mainForm = QConfigLayout() + self.mainForm.setHelpTextStyle(self.theTheme.helpText) + self.setLayout(self.mainForm) + + # GUI Settings + # ============ + self.mainForm.addGroupLabel("GUI") + + ## Select Theme + self.selectTheme = QComboBox() + self.selectTheme.setMinimumWidth(200) + self.theThemes = self.theTheme.listThemes() + for themeDir, themeName in self.theThemes: + self.selectTheme.addItem(themeName, themeDir) + themeIdx = self.selectTheme.findData(self.mainConf.guiTheme) + if themeIdx != -1: + self.selectTheme.setCurrentIndex(themeIdx) + + self.mainForm.addRow("Colour theme", self.selectTheme) + + ## Syntax Highlighting + self.selectSyntax = QComboBox() + self.selectSyntax.setMinimumWidth(200) + self.theSyntaxes = self.theTheme.listSyntax() + for syntaxFile, syntaxName in self.theSyntaxes: + self.selectSyntax.addItem(syntaxName, syntaxFile) + syntaxIdx = self.selectSyntax.findData(self.mainConf.guiSyntax) + if syntaxIdx != -1: + self.selectSyntax.setCurrentIndex(syntaxIdx) + + self.mainForm.addRow("Syntax highlight theme", self.selectSyntax) + + ## Dark Icons + self.preferDarkIcons = QSwitch() + self.preferDarkIcons.setChecked(self.mainConf.guiDark) + self.mainForm.addRow( + "Prefer icons for dark backgrounds", + self.preferDarkIcons, + "May improve the look of icons on dark themes" + ) + + # AutoSave Settings + # ================= + self.mainForm.addGroupLabel("Automatic Save") + + self.autoSaveDoc = QSpinBox(self) + self.autoSaveDoc.setMinimum(5) + self.autoSaveDoc.setMaximum(600) + self.autoSaveDoc.setSingleStep(1) + self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc) + self.backupPathRow = self.mainForm.addRow( + "Save interval for the currently open document", + self.autoSaveDoc, + theUnit="seconds" + ) + + self.autoSaveProj = QSpinBox(self) + self.autoSaveProj.setMinimum(5) + self.autoSaveProj.setMaximum(600) + self.autoSaveProj.setSingleStep(1) + self.autoSaveProj.setValue(self.mainConf.autoSaveProj) + self.backupPathRow = self.mainForm.addRow( + "Save interval for the currently open project", + self.autoSaveProj, + theUnit="seconds" + ) + + # Backup Settings + # =============== + self.mainForm.addGroupLabel("Project Backup") + + ## Backup Path + self.backupPath = self.mainConf.backupPath + self.backupGetPath = QPushButton(self.theTheme.getIcon("folder"),"Select Folder") + self.backupGetPath.clicked.connect(self._backupFolder) + self.backupPathRow = self.mainForm.addRow( + "Backup storage location", + self.backupGetPath, + "Path: %s" % self.backupPath + ) + + ## Run when closing + self.backupOnClose = QSwitch() + self.backupOnClose.setChecked(self.mainConf.backupOnClose) + self.backupOnClose.toggled.connect(self._toggledBackupOnClose) + self.mainForm.addRow( + "Run backup when closing project", + self.backupOnClose, + "This option can be overridden in project settings" + ) + + ## Ask before backup + self.askBeforeBackup = QSwitch() + self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup) + self.mainForm.addRow( + "Ask before running backup", + self.askBeforeBackup + ) + + return + + def saveValues(self): + + validEntries = True + needsRestart = False + + guiTheme = self.selectTheme.currentData() + guiSyntax = self.selectSyntax.currentData() + guiDark = self.preferDarkIcons.isChecked() + autoSaveDoc = self.autoSaveDoc.value() + autoSaveProj = self.autoSaveProj.value() + backupPath = self.backupPath + backupOnClose = self.backupOnClose.isChecked() + askBeforeBackup = self.askBeforeBackup.isChecked() + + # Check if restart is needed + needsRestart |= self.mainConf.guiTheme != guiTheme + + self.mainConf.guiTheme = guiTheme + self.mainConf.guiSyntax = guiSyntax + self.mainConf.guiDark = guiDark + self.mainConf.autoSaveDoc = autoSaveDoc + self.mainConf.autoSaveProj = autoSaveProj + self.mainConf.backupPath = backupPath + self.mainConf.backupOnClose = backupOnClose + self.mainConf.askBeforeBackup = askBeforeBackup + + self.mainConf.confChanged = True + + return validEntries, needsRestart + + ## + # Slots + ## + + def _backupFolder(self): + + currDir = self.backupPath + if not path.isdir(currDir): + currDir = "" + + dlgOpt = QFileDialog.Options() + dlgOpt |= QFileDialog.ShowDirsOnly + dlgOpt |= QFileDialog.DontUseNativeDialog + newDir = QFileDialog.getExistingDirectory( + self,"Backup Directory",currDir,options=dlgOpt + ) + if newDir: + self.backupPath = newDir + self.mainForm.setHelpText(self.backupPathRow, "Path: %s" % self.backupPath) + return True + + return False + + def _toggledBackupOnClose(self, theState): + """If "backup on close" is disabled, also disable "ask before + backup". + """ + if not theState: + self.askBeforeBackup.setChecked(False) + return + +# END Class GuiConfigEditGeneralTab + class GuiConfigEditGeneral(QWidget): def __init__(self, theParent): @@ -131,40 +313,6 @@ class GuiConfigEditGeneral(QWidget): self.theTheme = theParent.theTheme self.outerBox = QGridLayout() - # User Interface - self.guiLook = QGroupBox("User Interface", self) - self.guiLookForm = QGridLayout(self) - self.guiLook.setLayout(self.guiLookForm) - - self.guiLookTheme = QComboBox() - self.guiLookTheme.setMinimumWidth(200) - self.theThemes = self.theTheme.listThemes() - for themeDir, themeName in self.theThemes: - self.guiLookTheme.addItem(themeName, themeDir) - themeIdx = self.guiLookTheme.findData(self.mainConf.guiTheme) - if themeIdx != -1: - self.guiLookTheme.setCurrentIndex(themeIdx) - - self.guiLookSyntax = QComboBox() - self.guiLookSyntax.setMinimumWidth(200) - self.theSyntaxes = self.theTheme.listSyntax() - for syntaxFile, syntaxName in self.theSyntaxes: - self.guiLookSyntax.addItem(syntaxName, syntaxFile) - syntaxIdx = self.guiLookSyntax.findData(self.mainConf.guiSyntax) - if syntaxIdx != -1: - self.guiLookSyntax.setCurrentIndex(syntaxIdx) - - self.guiDarkIcons = QCheckBox("Prefer icons for dark backgrounds", self) - self.guiDarkIcons.setToolTip("This may improve the look of icons if the system theme is dark.") - self.guiDarkIcons.setChecked(self.mainConf.guiDark) - - self.guiLookForm.addWidget(QLabel("Theme"), 0, 0) - self.guiLookForm.addWidget(self.guiLookTheme, 0, 1) - self.guiLookForm.addWidget(QLabel("Syntax"), 1, 0) - self.guiLookForm.addWidget(self.guiLookSyntax, 1, 1) - self.guiLookForm.addWidget(self.guiDarkIcons, 2, 0, 1, 2) - self.guiLookForm.setColumnStretch(3, 1) - # Spell Checking self.spellLang = QGroupBox("Spell Checker", self) self.spellLangForm = QGridLayout(self) @@ -207,62 +355,8 @@ class GuiConfigEditGeneral(QWidget): self.spellLangForm.addWidget(QLabel("kb"), 2, 2) self.spellLangForm.setColumnStretch(4, 1) - # AutoSave - self.autoSave = QGroupBox("Automatic Save", self) - self.autoSaveForm = QGridLayout(self) - self.autoSave.setLayout(self.autoSaveForm) - - self.autoSaveDoc = QSpinBox(self) - self.autoSaveDoc.setMinimum(5) - self.autoSaveDoc.setMaximum(600) - self.autoSaveDoc.setSingleStep(1) - self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc) - - self.autoSaveProj = QSpinBox(self) - self.autoSaveProj.setMinimum(5) - self.autoSaveProj.setMaximum(600) - self.autoSaveProj.setSingleStep(1) - self.autoSaveProj.setValue(self.mainConf.autoSaveProj) - - self.autoSaveForm.addWidget(QLabel("Document"), 0, 0) - self.autoSaveForm.addWidget(self.autoSaveDoc, 0, 1) - self.autoSaveForm.addWidget(QLabel("seconds"), 0, 2) - self.autoSaveForm.addWidget(QLabel("Project"), 1, 0) - self.autoSaveForm.addWidget(self.autoSaveProj, 1, 1) - self.autoSaveForm.addWidget(QLabel("seconds"), 1, 2) - self.autoSaveForm.setColumnStretch(3, 1) - - # Backup - self.projBackup = QGroupBox("Backup Folder", self) - self.projBackupForm = QGridLayout(self) - self.projBackup.setLayout(self.projBackupForm) - - self.projBackupPath = QLineEdit() - if path.isdir(self.mainConf.backupPath): - self.projBackupPath.setText(self.mainConf.backupPath) - - self.projBackupGetPath = QPushButton(self.theTheme.getIcon("folder"),"") - self.projBackupGetPath.clicked.connect(self._backupFolder) - - self.projBackupClose = QCheckBox("Run on close",self) - self.projBackupClose.setToolTip("Backup automatically on project close.") - self.projBackupClose.setChecked(self.mainConf.backupOnClose) - - self.projBackupAsk = QCheckBox("Ask before backup",self) - self.projBackupAsk.setToolTip("Ask before backup.") - self.projBackupAsk.setChecked(self.mainConf.askBeforeBackup) - - self.projBackupForm.addWidget(self.projBackupPath, 0, 0, 1, 2) - self.projBackupForm.addWidget(self.projBackupGetPath, 0, 2) - self.projBackupForm.addWidget(self.projBackupClose, 1, 0) - self.projBackupForm.addWidget(self.projBackupAsk, 1, 1, 1, 2) - self.projBackupForm.setColumnStretch(1, 1) - # Assemble - self.outerBox.addWidget(self.guiLook, 0, 0) self.outerBox.addWidget(self.spellLang, 1, 0) - self.outerBox.addWidget(self.autoSave, 2, 0) - self.outerBox.addWidget(self.projBackup, 3, 0, 1, 2) self.outerBox.setColumnStretch(1, 1) self.outerBox.setRowStretch(4, 1) self.setLayout(self.outerBox) @@ -274,32 +368,13 @@ class GuiConfigEditGeneral(QWidget): validEntries = True needsRestart = False - guiTheme = self.guiLookTheme.currentData() - guiSyntax = self.guiLookSyntax.currentData() - guiDark = self.guiDarkIcons.isChecked() spellTool = self.spellToolList.currentData() spellLanguage = self.spellLangList.currentData() bigDocLimit = self.spellBigDoc.value() - autoSaveDoc = self.autoSaveDoc.value() - autoSaveProj = self.autoSaveProj.value() - backupPath = self.projBackupPath.text() - backupOnClose = self.projBackupClose.isChecked() - askBeforeBackup = self.projBackupAsk.isChecked() - # Check if restart is needed - needsRestart |= self.mainConf.guiTheme != guiTheme - - self.mainConf.guiTheme = guiTheme - self.mainConf.guiSyntax = guiSyntax - self.mainConf.guiDark = guiDark self.mainConf.spellTool = spellTool self.mainConf.spellLanguage = spellLanguage self.mainConf.bigDocLimit = bigDocLimit - self.mainConf.autoSaveDoc = autoSaveDoc - self.mainConf.autoSaveProj = autoSaveProj - self.mainConf.backupPath = backupPath - self.mainConf.backupOnClose = backupOnClose - self.mainConf.askBeforeBackup = askBeforeBackup self.mainConf.confChanged = True @@ -309,24 +384,6 @@ class GuiConfigEditGeneral(QWidget): # Internal Functions ## - def _backupFolder(self): - - currDir = self.projBackupPath.text() - if not path.isdir(currDir): - currDir = "" - - dlgOpt = QFileDialog.Options() - dlgOpt |= QFileDialog.ShowDirsOnly - dlgOpt |= QFileDialog.DontUseNativeDialog - newDir = QFileDialog.getExistingDirectory( - self,"Backup Directory",currDir,options=dlgOpt - ) - if newDir: - self.projBackupPath.setText(newDir) - return True - - return False - def _disableComboItem(self, theList, theValue): theIdx = theList.findData(theValue) theModel = theList.model() diff --git a/nw/gui/theme.py b/nw/gui/theme.py index 00463aac..2cdc1b2f 100644 --- a/nw/gui/theme.py +++ b/nw/gui/theme.py @@ -68,6 +68,7 @@ class GuiTheme: self.statNone = [120,120,120] self.statUnsaved = [120,120, 40] self.statSaved = [ 40,120, 0] + self.helpText = [ 0, 0, 0] # Loaded Syntax Settings @@ -121,6 +122,8 @@ class GuiTheme: ## def updateTheme(self): + """Update the GUI theme from theme files. + """ self.guiTheme = self.mainConf.guiTheme self.guiSyntax = self.mainConf.guiSyntax @@ -135,6 +138,20 @@ class GuiTheme: self.loadTheme() self.loadSyntax() + # Update dependant colours + backCol = qApp.palette().window().color() + textCol = qApp.palette().windowText().color() + + backLCol = backCol.lightnessF() + textLCol = textCol.lightnessF() + + if backLCol > textLCol: + helpLCol = textLCol + 0.65*(backLCol - textLCol) + else: + helpLCol = backLCol + 0.65*(textLCol - backLCol) + + self.helpText = [int(255*helpLCol)]*3 + return True def loadTheme(self): From 6c0c9089896fbe0570a60041a644e9796be66ccc Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 18:02:27 +0200 Subject: [PATCH 05/10] Added Layout tab to main config dialog --- nw/additions/qconfiglayout.py | 2 +- nw/gui/dialogs/configeditor.py | 256 ++++++++++++++++++--------------- 2 files changed, 141 insertions(+), 117 deletions(-) diff --git a/nw/additions/qconfiglayout.py b/nw/additions/qconfiglayout.py index 431c9825..0e413da6 100644 --- a/nw/additions/qconfiglayout.py +++ b/nw/additions/qconfiglayout.py @@ -89,7 +89,7 @@ class QConfigLayout(QGridLayout): if isinstance(theLabel, QLabel): qLabel = theLabel elif isinstance(theLabel, str): - qLabel = QLabel(theLabel) + qLabel = QLabel("%s" % theLabel) else: qLabel = None raise ValueError("theLabel must be a QLabel") diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index cd85f10e..be46a7ee 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -61,12 +61,14 @@ class GuiConfigEditor(QDialog): self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64)) self.tabGeneral = GuiConfigEditGeneralTab(self.theParent) + self.tabLayout = GuiConfigEditLayoutTab(self.theParent) self.tabMain = GuiConfigEditGeneral(self.theParent) self.tabEditor = GuiConfigEditEditor(self.theParent) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(600) self.tabWidget.addTab(self.tabGeneral, "General") + self.tabWidget.addTab(self.tabLayout, "Layout") self.tabWidget.addTab(self.tabMain, "General") self.tabWidget.addTab(self.tabEditor, "Editor") @@ -102,6 +104,10 @@ class GuiConfigEditor(QDialog): validEntries &= retA needsRestart |= retB + retA, retB = self.tabLayout.saveValues() + validEntries &= retA + needsRestart |= retB + retA, retB = self.tabMain.saveValues() validEntries &= retA needsRestart |= retB @@ -303,6 +309,140 @@ class GuiConfigEditGeneralTab(QWidget): # END Class GuiConfigEditGeneralTab +class GuiConfigEditLayoutTab(QWidget): + + def __init__(self, theParent): + QWidget.__init__(self, theParent) + + self.mainConf = nw.CONFIG + self.theParent = theParent + self.theTheme = theParent.theTheme + + # The Form + self.mainForm = QConfigLayout() + self.mainForm.setHelpTextStyle(self.theTheme.helpText) + self.setLayout(self.mainForm) + + # Text Style + # ========== + self.mainForm.addGroupLabel("Text Style") + + self.textStyleFont = QFontComboBox() + self.textStyleFont.setMaximumWidth(200) + self.textStyleFont.setCurrentFont(QFont(self.mainConf.textFont)) + self.mainForm.addRow( + "Font family", + self.textStyleFont, + "For the document editor and viewer" + ) + + self.textStyleSize = QSpinBox(self) + self.textStyleSize.setMinimum(5) + self.textStyleSize.setMaximum(120) + self.textStyleSize.setSingleStep(1) + self.textStyleSize.setValue(self.mainConf.textSize) + self.mainForm.addRow( + "Font size", + self.textStyleSize, + theUnit="pt" + ) + + # Text Flow + # ========= + self.mainForm.addGroupLabel("Text Flow") + + self.textFlowMax = QSpinBox(self) + self.textFlowMax.setMinimum(300) + self.textFlowMax.setMaximum(10000) + self.textFlowMax.setSingleStep(10) + self.textFlowMax.setValue(self.mainConf.textWidth) + self.mainForm.addRow( + "Maximum text width in Normal mode", + self.textFlowMax, + theUnit="px" + ) + + self.zenDocWidth = QSpinBox(self) + self.zenDocWidth.setMinimum(300) + self.zenDocWidth.setMaximum(10000) + self.zenDocWidth.setSingleStep(10) + self.zenDocWidth.setValue(self.mainConf.zenWidth) + self.mainForm.addRow( + "Maximum text width in Zen mode", + self.zenDocWidth, + theUnit="px" + ) + + self.textFlowFixed = QSwitch() + self.textFlowFixed.setChecked(not self.mainConf.textFixedW) + self.mainForm.addRow( + "Disable maximum text width in Normal mode", + self.textFlowFixed, + "Only fixed margins are applied to the document" + ) + + self.textJustify = QSwitch() + self.textJustify.setChecked(self.mainConf.textFixedW) + self.mainForm.addRow( + "Justify the text margins in editor and viewer", + self.textJustify + ) + + self.textMargin = QSpinBox(self) + self.textMargin.setMinimum(0) + self.textMargin.setMaximum(2000) + self.textMargin.setSingleStep(1) + self.textMargin.setValue(self.mainConf.textMargin) + self.mainForm.addRow( + "Document text margin", + self.textMargin, + "The minimum horizontal text margin if max with is enabled", + theUnit="px" + ) + + self.tabWidth = QSpinBox(self) + self.tabWidth.setMinimum(0) + self.tabWidth.setMaximum(200) + self.tabWidth.setSingleStep(1) + self.tabWidth.setValue(self.mainConf.tabWidth) + self.mainForm.addRow( + "Editor tab width", + self.tabWidth, + "This feature requires Qt 5.9 or later", + theUnit="px" + ) + + return + + def saveValues(self): + + validEntries = True + needsRestart = False + + textFont = self.textStyleFont.currentFont().family() + textSize = self.textStyleSize.value() + textWidth = self.textFlowMax.value() + zenWidth = self.zenDocWidth.value() + textFixedW = not self.textFlowFixed.isChecked() + doJustify = self.textJustify.isChecked() + textMargin = self.textMargin.value() + tabWidth = self.tabWidth.value() + + self.mainConf.textFont = textFont + self.mainConf.textSize = textSize + self.mainConf.textWidth = textWidth + self.mainConf.zenWidth = zenWidth + self.mainConf.textFixedW = textFixedW + self.mainConf.doJustify = doJustify + self.mainConf.textMargin = textMargin + self.mainConf.tabWidth = tabWidth + + self.mainConf.confChanged = True + + return validEntries, needsRestart + +# END Class GuiConfigEditLayoutTab + class GuiConfigEditGeneral(QWidget): def __init__(self, theParent): @@ -428,94 +568,6 @@ class GuiConfigEditEditor(QWidget): self.theParent = theParent self.outerBox = QGridLayout() - # Text Style - self.textStyle = QGroupBox("Text Style", self) - self.textStyleForm = QGridLayout(self) - self.textStyle.setLayout(self.textStyleForm) - - self.textStyleFont = QFontComboBox() - self.textStyleFont.setMaximumWidth(250) - self.textStyleFont.setCurrentFont(QFont(self.mainConf.textFont)) - - self.textStyleSize = QSpinBox(self) - self.textStyleSize.setMinimum(5) - self.textStyleSize.setMaximum(120) - self.textStyleSize.setSingleStep(1) - self.textStyleSize.setValue(self.mainConf.textSize) - - self.textStyleForm.addWidget(QLabel("Font family"), 0, 0) - self.textStyleForm.addWidget(self.textStyleFont, 0, 1) - self.textStyleForm.addWidget(QLabel("Size"), 0, 2) - self.textStyleForm.addWidget(self.textStyleSize, 0, 3) - self.textStyleForm.setColumnStretch(4, 1) - - # Text Flow - self.textFlow = QGroupBox("Text Flow", self) - self.textFlowForm = QGridLayout(self) - self.textFlow.setLayout(self.textFlowForm) - - self.textFlowFixed = QCheckBox("Max text width",self) - self.textFlowFixed.setToolTip("Maximum width of the text.") - self.textFlowFixed.setChecked(self.mainConf.textFixedW) - - self.textFlowMax = QSpinBox(self) - self.textFlowMax.setMinimum(300) - self.textFlowMax.setMaximum(10000) - self.textFlowMax.setSingleStep(10) - self.textFlowMax.setValue(self.mainConf.textWidth) - - self.textFlowJustify = QCheckBox("Justify text",self) - self.textFlowJustify.setToolTip("Justify text in main document editor.") - self.textFlowJustify.setChecked(self.mainConf.doJustify) - - self.textFlowForm.addWidget(self.textFlowFixed, 0, 0) - self.textFlowForm.addWidget(self.textFlowMax, 0, 1) - self.textFlowForm.addWidget(QLabel("px"), 0, 2) - self.textFlowForm.addWidget(self.textFlowJustify, 1, 0) - self.textFlowForm.setColumnStretch(4, 1) - - # Text Margins - self.textMargin = QGroupBox("Margins", self) - self.textMarginForm = QGridLayout(self) - self.textMargin.setLayout(self.textMarginForm) - - self.textMarginDoc = QSpinBox(self) - self.textMarginDoc.setMinimum(0) - self.textMarginDoc.setMaximum(2000) - self.textMarginDoc.setSingleStep(1) - self.textMarginDoc.setValue(self.mainConf.textMargin) - - self.textMarginTab = QSpinBox(self) - self.textMarginTab.setMinimum(0) - self.textMarginTab.setMaximum(200) - self.textMarginTab.setSingleStep(1) - self.textMarginTab.setValue(self.mainConf.tabWidth) - self.textMarginTab.setToolTip("Requires Qt 5.9 or later.") - - self.textMarginForm.addWidget(QLabel("Document"), 0, 0) - self.textMarginForm.addWidget(self.textMarginDoc, 0, 1) - self.textMarginForm.addWidget(QLabel("px"), 0, 2) - self.textMarginForm.addWidget(QLabel("Tab width"), 2, 0) - self.textMarginForm.addWidget(self.textMarginTab, 2, 1) - self.textMarginForm.addWidget(QLabel("px"), 2, 2) - self.textMarginForm.setColumnStretch(4, 1) - - # Zen Mode - self.zenMode = QGroupBox("Zen Mode", self) - self.zenModeForm = QGridLayout(self) - self.zenMode.setLayout(self.zenModeForm) - - self.zenDocWidth = QSpinBox(self) - self.zenDocWidth.setMinimum(300) - self.zenDocWidth.setMaximum(10000) - self.zenDocWidth.setSingleStep(10) - self.zenDocWidth.setValue(self.mainConf.zenWidth) - - self.zenModeForm.addWidget(QLabel("Document width"), 0, 0) - self.zenModeForm.addWidget(self.zenDocWidth, 0, 1) - self.zenModeForm.addWidget(QLabel("px"), 0, 2) - self.zenModeForm.setColumnStretch(3, 1) - # Automatic Features self.autoReplace = QGroupBox("Automatic Features", self) self.autoReplaceForm = QGridLayout(self) @@ -619,10 +671,6 @@ class GuiConfigEditEditor(QWidget): self.showGuidesForm.addWidget(self.showLineEndings, 1, 0) # Assemble - self.outerBox.addWidget(self.textStyle, 0, 0, 1, 2) - self.outerBox.addWidget(self.textFlow, 1, 0) - self.outerBox.addWidget(self.textMargin, 1, 1) - self.outerBox.addWidget(self.zenMode, 2, 0) self.outerBox.addWidget(self.autoReplace, 3, 0, 2, 1) self.outerBox.addWidget(self.quoteStyle, 2, 1, 2, 1) self.outerBox.addWidget(self.showGuides, 4, 1) @@ -636,30 +684,6 @@ class GuiConfigEditEditor(QWidget): validEntries = True - textFont = self.textStyleFont.currentFont().family() - textSize = self.textStyleSize.value() - - self.mainConf.textFont = textFont - self.mainConf.textSize = textSize - - textWidth = self.textFlowMax.value() - textFixedW = self.textFlowFixed.isChecked() - doJustify = self.textFlowJustify.isChecked() - - self.mainConf.textWidth = textWidth - self.mainConf.textFixedW = textFixedW - self.mainConf.doJustify = doJustify - - zenWidth = self.zenDocWidth.value() - - self.mainConf.zenWidth = zenWidth - - textMargin = self.textMarginDoc.value() - tabWidth = self.textMarginTab.value() - - self.mainConf.textMargin = textMargin - self.mainConf.tabWidth = tabWidth - autoSelect = self.autoSelect.isChecked() doReplace = self.autoReplaceMain.isChecked() doReplaceSQuote = self.autoReplaceSQ.isChecked() From 0e0b61be8ca90da15608e0d29090064f7cb885a6 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 19:10:00 +0200 Subject: [PATCH 06/10] Moved config of spell check and qriting guides --- nw/gui/dialogs/configeditor.py | 182 ++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 80 deletions(-) diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index be46a7ee..3ee8588d 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -62,14 +62,14 @@ class GuiConfigEditor(QDialog): self.tabGeneral = GuiConfigEditGeneralTab(self.theParent) self.tabLayout = GuiConfigEditLayoutTab(self.theParent) - self.tabMain = GuiConfigEditGeneral(self.theParent) + self.tabEditing = GuiConfigEditEditingTab(self.theParent) self.tabEditor = GuiConfigEditEditor(self.theParent) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(600) self.tabWidget.addTab(self.tabGeneral, "General") - self.tabWidget.addTab(self.tabLayout, "Layout") - self.tabWidget.addTab(self.tabMain, "General") + self.tabWidget.addTab(self.tabLayout, "Layout") + self.tabWidget.addTab(self.tabEditing, "Editing") self.tabWidget.addTab(self.tabEditor, "Editor") self.setLayout(self.outerBox) @@ -108,7 +108,7 @@ class GuiConfigEditor(QDialog): validEntries &= retA needsRestart |= retB - retA, retB = self.tabMain.saveValues() + retA, retB = self.tabEditing.saveValues() validEntries &= retA needsRestart |= retB @@ -183,7 +183,7 @@ class GuiConfigEditGeneralTab(QWidget): self.mainForm.addRow( "Prefer icons for dark backgrounds", self.preferDarkIcons, - "May improve the look of icons on dark themes" + "May improve the look of icons on dark themes." ) # AutoSave Settings @@ -233,7 +233,7 @@ class GuiConfigEditGeneralTab(QWidget): self.mainForm.addRow( "Run backup when closing project", self.backupOnClose, - "This option can be overridden in project settings" + "This option can be overridden in project settings." ) ## Ask before backup @@ -333,7 +333,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Font family", self.textStyleFont, - "For the document editor and viewer" + "For the document editor and viewer." ) self.textStyleSize = QSpinBox(self) @@ -378,7 +378,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Disable maximum text width in Normal mode", self.textFlowFixed, - "Only fixed margins are applied to the document" + "Only fixed margins are applied to the document." ) self.textJustify = QSwitch() @@ -390,13 +390,13 @@ class GuiConfigEditLayoutTab(QWidget): self.textMargin = QSpinBox(self) self.textMargin.setMinimum(0) - self.textMargin.setMaximum(2000) + self.textMargin.setMaximum(900) self.textMargin.setSingleStep(1) self.textMargin.setValue(self.mainConf.textMargin) self.mainForm.addRow( "Document text margin", self.textMargin, - "The minimum horizontal text margin if max with is enabled", + "The minimum horizontal text margin if max with is enabled.", theUnit="px" ) @@ -408,10 +408,28 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Editor tab width", self.tabWidth, - "This feature requires Qt 5.9 or later", + "This feature requires Qt 5.9 or later.", theUnit="px" ) + # Writing Guides + # ============== + self.mainForm.addGroupLabel("Writing Guides") + + self.showTabsNSpaces = QSwitch() + self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) + self.mainForm.addRow( + "Show tabs and spaces", + self.showTabsNSpaces + ) + + self.showLineEndings = QSwitch() + self.showLineEndings.setChecked(self.mainConf.showLineEndings) + self.mainForm.addRow( + "Show line endings", + self.showLineEndings + ) + return def saveValues(self): @@ -419,23 +437,27 @@ class GuiConfigEditLayoutTab(QWidget): validEntries = True needsRestart = False - textFont = self.textStyleFont.currentFont().family() - textSize = self.textStyleSize.value() - textWidth = self.textFlowMax.value() - zenWidth = self.zenDocWidth.value() - textFixedW = not self.textFlowFixed.isChecked() - doJustify = self.textJustify.isChecked() - textMargin = self.textMargin.value() - tabWidth = self.tabWidth.value() + textFont = self.textStyleFont.currentFont().family() + textSize = self.textStyleSize.value() + textWidth = self.textFlowMax.value() + zenWidth = self.zenDocWidth.value() + textFixedW = not self.textFlowFixed.isChecked() + doJustify = self.textJustify.isChecked() + textMargin = self.textMargin.value() + tabWidth = self.tabWidth.value() + showTabsNSpaces = self.showTabsNSpaces.isChecked() + showLineEndings = self.showLineEndings.isChecked() - self.mainConf.textFont = textFont - self.mainConf.textSize = textSize - self.mainConf.textWidth = textWidth - self.mainConf.zenWidth = zenWidth - self.mainConf.textFixedW = textFixedW - self.mainConf.doJustify = doJustify - self.mainConf.textMargin = textMargin - self.mainConf.tabWidth = tabWidth + self.mainConf.textFont = textFont + self.mainConf.textSize = textSize + self.mainConf.textWidth = textWidth + self.mainConf.zenWidth = zenWidth + self.mainConf.textFixedW = textFixedW + self.mainConf.doJustify = doJustify + self.mainConf.textMargin = textMargin + self.mainConf.tabWidth = tabWidth + self.mainConf.showTabsNSpaces = showTabsNSpaces + self.mainConf.showLineEndings = showLineEndings self.mainConf.confChanged = True @@ -443,7 +465,7 @@ class GuiConfigEditLayoutTab(QWidget): # END Class GuiConfigEditLayoutTab -class GuiConfigEditGeneral(QWidget): +class GuiConfigEditEditingTab(QWidget): def __init__(self, theParent): QWidget.__init__(self, theParent) @@ -451,24 +473,27 @@ class GuiConfigEditGeneral(QWidget): self.mainConf = nw.CONFIG self.theParent = theParent self.theTheme = theParent.theTheme - self.outerBox = QGridLayout() + + # The Form + self.mainForm = QConfigLayout() + self.mainForm.setHelpTextStyle(self.theTheme.helpText) + self.setLayout(self.mainForm) # Spell Checking - self.spellLang = QGroupBox("Spell Checker", self) - self.spellLangForm = QGridLayout(self) - self.spellLang.setLayout(self.spellLangForm) + # ============== + self.mainForm.addGroupLabel("Spell Checking") self.spellLangList = QComboBox(self) self.spellToolList = QComboBox(self) self.spellToolList.addItem("Internal (difflib)", NWSpellCheck.SP_INTERNAL) self.spellToolList.addItem("Spell Enchant (pyenchant)", NWSpellCheck.SP_ENCHANT) - self.spellToolList.addItem("SymSpell (symspellpy)", NWSpellCheck.SP_SYMSPELL) + # self.spellToolList.addItem("SymSpell (symspellpy)", NWSpellCheck.SP_SYMSPELL) theModel = self.spellToolList.model() idEnchant = self.spellToolList.findData(NWSpellCheck.SP_ENCHANT) - idSymSpell = self.spellToolList.findData(NWSpellCheck.SP_SYMSPELL) + # idSymSpell = self.spellToolList.findData(NWSpellCheck.SP_SYMSPELL) theModel.item(idEnchant).setEnabled(self.mainConf.hasEnchant) - theModel.item(idSymSpell).setEnabled(self.mainConf.hasSymSpell) + # theModel.item(idSymSpell).setEnabled(self.mainConf.hasSymSpell) self.spellToolList.currentIndexChanged.connect(self._doUpdateSpellTool) toolIdx = self.spellToolList.findData(self.mainConf.spellTool) @@ -476,30 +501,27 @@ class GuiConfigEditGeneral(QWidget): self.spellToolList.setCurrentIndex(toolIdx) self._doUpdateSpellTool(0) - self.spellBigDoc = QSpinBox(self) - self.spellBigDoc.setMinimum(10) - self.spellBigDoc.setMaximum(10000) - self.spellBigDoc.setSingleStep(10) - self.spellBigDoc.setToolTip(( - "Disable spell checking when loading large documents. " - "Spell checking will only run on paragraphs you edit." - )) - self.spellBigDoc.setValue(self.mainConf.bigDocLimit) + self.mainForm.addRow( + "Spell check provider", + self.spellToolList, + "Note that the internal spell check tool is quite slow." + ) + self.mainForm.addRow( + "Spell check language", + self.spellLangList + ) - self.spellLangForm.addWidget(QLabel("Provider"), 0, 0) - self.spellLangForm.addWidget(self.spellToolList, 0, 1, 1, 3) - self.spellLangForm.addWidget(QLabel("Language"), 1, 0) - self.spellLangForm.addWidget(self.spellLangList, 1, 1, 1, 3) - self.spellLangForm.addWidget(QLabel("Size limit"), 2, 0) - self.spellLangForm.addWidget(self.spellBigDoc, 2, 1) - self.spellLangForm.addWidget(QLabel("kb"), 2, 2) - self.spellLangForm.setColumnStretch(4, 1) - - # Assemble - self.outerBox.addWidget(self.spellLang, 1, 0) - self.outerBox.setColumnStretch(1, 1) - self.outerBox.setRowStretch(4, 1) - self.setLayout(self.outerBox) + self.bigDocLimit = QSpinBox(self) + self.bigDocLimit.setMinimum(10) + self.bigDocLimit.setMaximum(10000) + self.bigDocLimit.setSingleStep(10) + self.bigDocLimit.setValue(self.mainConf.bigDocLimit) + self.mainForm.addRow( + "Big document limit", + self.bigDocLimit, + "Disables full spell checking over the size limit.", + theUnit="kb" + ) return @@ -508,13 +530,13 @@ class GuiConfigEditGeneral(QWidget): validEntries = True needsRestart = False - spellTool = self.spellToolList.currentData() - spellLanguage = self.spellLangList.currentData() - bigDocLimit = self.spellBigDoc.value() + spellTool = self.spellToolList.currentData() + spellLanguage = self.spellLangList.currentData() + bigDocLimit = self.bigDocLimit.value() - self.mainConf.spellTool = spellTool - self.mainConf.spellLanguage = spellLanguage - self.mainConf.bigDocLimit = bigDocLimit + self.mainConf.spellTool = spellTool + self.mainConf.spellLanguage = spellLanguage + self.mainConf.bigDocLimit = bigDocLimit self.mainConf.confChanged = True @@ -557,7 +579,7 @@ class GuiConfigEditGeneral(QWidget): return -# END Class GuiConfigEditGeneral +# END Class GuiConfigEditEditingTab class GuiConfigEditEditor(QWidget): @@ -656,24 +678,24 @@ class GuiConfigEditEditor(QWidget): self.quoteStyleForm.setColumnStretch(4, 1) self.quoteStyleForm.setRowStretch(4, 1) - # Writing Guides - self.showGuides = QGroupBox("Writing Guides", self) - self.showGuidesForm = QGridLayout(self) - self.showGuides.setLayout(self.showGuidesForm) + # # Writing Guides + # self.showGuides = QGroupBox("Writing Guides", self) + # self.showGuidesForm = QGridLayout(self) + # self.showGuides.setLayout(self.showGuidesForm) - self.showTabsNSpaces = QCheckBox("Show tabs and spaces",self) - self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) + # self.showTabsNSpaces = QCheckBox("Show tabs and spaces",self) + # self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) - self.showLineEndings = QCheckBox("Show line endings",self) - self.showLineEndings.setChecked(self.mainConf.showLineEndings) + # self.showLineEndings = QCheckBox("Show line endings",self) + # self.showLineEndings.setChecked(self.mainConf.showLineEndings) - self.showGuidesForm.addWidget(self.showTabsNSpaces, 0, 0) - self.showGuidesForm.addWidget(self.showLineEndings, 1, 0) + # self.showGuidesForm.addWidget(self.showTabsNSpaces, 0, 0) + # self.showGuidesForm.addWidget(self.showLineEndings, 1, 0) # Assemble self.outerBox.addWidget(self.autoReplace, 3, 0, 2, 1) self.outerBox.addWidget(self.quoteStyle, 2, 1, 2, 1) - self.outerBox.addWidget(self.showGuides, 4, 1) + # self.outerBox.addWidget(self.showGuides, 4, 1) self.outerBox.setColumnStretch(2, 1) self.outerBox.setRowStretch(5, 1) self.setLayout(self.outerBox) @@ -735,11 +757,11 @@ class GuiConfigEditEditor(QWidget): ) validEntries = False - showTabsNSpaces = self.showTabsNSpaces.isChecked() - showLineEndings = self.showLineEndings.isChecked() + # showTabsNSpaces = self.showTabsNSpaces.isChecked() + # showLineEndings = self.showLineEndings.isChecked() - self.mainConf.showTabsNSpaces = showTabsNSpaces - self.mainConf.showLineEndings = showLineEndings + # self.mainConf.showTabsNSpaces = showTabsNSpaces + # self.mainConf.showLineEndings = showLineEndings self.mainConf.confChanged = True From 488521639569d5714907294b3fe0f79743358b77 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 19:24:25 +0200 Subject: [PATCH 07/10] Fnisished main config editing tab --- nw/gui/dialogs/configeditor.py | 180 ++++++++++++++++----------------- 1 file changed, 88 insertions(+), 92 deletions(-) diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index 3ee8588d..5c40b8ca 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -300,11 +300,10 @@ class GuiConfigEditGeneralTab(QWidget): return False def _toggledBackupOnClose(self, theState): - """If "backup on close" is disabled, also disable "ask before - backup". + """Enable or disable switch that depends on the backup on close + switch, """ - if not theState: - self.askBeforeBackup.setChecked(False) + self.askBeforeBackup.setEnabled(theState) return # END Class GuiConfigEditGeneralTab @@ -523,6 +522,59 @@ class GuiConfigEditEditingTab(QWidget): theUnit="kb" ) + # Automatic Features + # ================== + self.mainForm.addGroupLabel("Automatic Features") + + self.autoSelect = QSwitch() + self.autoSelect.setChecked(self.mainConf.autoSelect) + self.mainForm.addRow( + "Auto-select word under cursor", + self.autoSelect, + "Apply formatting to word under cursor if no selection is made." + ) + + self.autoReplaceMain = QSwitch() + self.autoReplaceMain.setChecked(self.mainConf.doReplace) + self.autoReplaceMain.toggled.connect(self._toggleAutoReplaceMain) + self.mainForm.addRow( + "Auto-replace text as you type", + self.autoReplaceMain, + "Apply formatting to word under cursor if no selection is made." + ) + + self.autoReplaceSQ = QSwitch() + self.autoReplaceSQ.setChecked(self.mainConf.doReplaceSQuote) + self.mainForm.addRow( + "Auto-replace single quotes", + self.autoReplaceSQ, + "The feature will try to guess opening or closing symbol." + ) + + self.autoReplaceDQ = QSwitch() + self.autoReplaceDQ.setChecked(self.mainConf.doReplaceDQuote) + self.mainForm.addRow( + "Auto-replace double quotes", + self.autoReplaceDQ, + "The feature will try to guess opening or closing symbol." + ) + + self.autoReplaceDash = QSwitch() + self.autoReplaceDash.setChecked(self.mainConf.doReplaceDash) + self.mainForm.addRow( + "Auto-replace dashes", + self.autoReplaceDash, + "Auto-replace double and triple hyphens with short and long dash." + ) + + self.autoReplaceDots = QSwitch() + self.autoReplaceDots.setChecked(self.mainConf.doReplaceDots) + self.mainForm.addRow( + "Auto-replace dots", + self.autoReplaceDots, + "Auto-replace three dots with ellipsis." + ) + return def saveValues(self): @@ -530,18 +582,44 @@ class GuiConfigEditEditingTab(QWidget): validEntries = True needsRestart = False - spellTool = self.spellToolList.currentData() - spellLanguage = self.spellLangList.currentData() - bigDocLimit = self.bigDocLimit.value() + spellTool = self.spellToolList.currentData() + spellLanguage = self.spellLangList.currentData() + bigDocLimit = self.bigDocLimit.value() + autoSelect = self.autoSelect.isChecked() + doReplace = self.autoReplaceMain.isChecked() + doReplaceSQuote = self.autoReplaceSQ.isChecked() + doReplaceDQuote = self.autoReplaceDQ.isChecked() + doReplaceDash = self.autoReplaceDash.isChecked() + doReplaceDots = self.autoReplaceDots.isChecked() - self.mainConf.spellTool = spellTool - self.mainConf.spellLanguage = spellLanguage - self.mainConf.bigDocLimit = bigDocLimit + self.mainConf.spellTool = spellTool + self.mainConf.spellLanguage = spellLanguage + self.mainConf.bigDocLimit = bigDocLimit + self.mainConf.autoSelect = autoSelect + self.mainConf.doReplace = doReplace + self.mainConf.doReplaceSQuote = doReplaceSQuote + self.mainConf.doReplaceDQuote = doReplaceDQuote + self.mainConf.doReplaceDash = doReplaceDash + self.mainConf.doReplaceDots = doReplaceDots self.mainConf.confChanged = True return validEntries, needsRestart + ## + # Slots + ## + + def _toggleAutoReplaceMain(self, theState): + """Enables or disables switches controlled by the main auto + replace switch. + """ + self.autoReplaceSQ.setEnabled(theState) + self.autoReplaceDQ.setEnabled(theState) + self.autoReplaceDash.setEnabled(theState) + self.autoReplaceDots.setEnabled(theState) + return + ## # Internal Functions ## @@ -590,52 +668,6 @@ class GuiConfigEditEditor(QWidget): self.theParent = theParent self.outerBox = QGridLayout() - # Automatic Features - self.autoReplace = QGroupBox("Automatic Features", self) - self.autoReplaceForm = QGridLayout(self) - self.autoReplace.setLayout(self.autoReplaceForm) - - self.autoSelect = QCheckBox(self) - self.autoSelect.setToolTip("Auto-select word under cursor when applying formatting.") - self.autoSelect.setChecked(self.mainConf.autoSelect) - - self.autoReplaceMain = QCheckBox(self) - self.autoReplaceMain.setToolTip("Auto-replace text as you type.") - self.autoReplaceMain.setChecked(self.mainConf.doReplace) - - self.autoReplaceSQ = QCheckBox(self) - self.autoReplaceSQ.setToolTip("Auto-replace single quotes.") - self.autoReplaceSQ.setChecked(self.mainConf.doReplaceSQuote) - - self.autoReplaceDQ = QCheckBox(self) - self.autoReplaceDQ.setToolTip("Auto-replace double quotes.") - self.autoReplaceDQ.setChecked(self.mainConf.doReplaceDQuote) - - self.autoReplaceDash = QCheckBox(self) - self.autoReplaceDash.setToolTip( - "Auto-replace double and triple hyphens with short and long dash." - ) - self.autoReplaceDash.setChecked(self.mainConf.doReplaceDash) - - self.autoReplaceDots = QCheckBox(self) - self.autoReplaceDots.setToolTip("Auto-replace three dots with ellipsis.") - self.autoReplaceDots.setChecked(self.mainConf.doReplaceDots) - - self.autoReplaceForm.addWidget(QLabel("Auto-select text"), 0, 0) - self.autoReplaceForm.addWidget(self.autoSelect, 0, 1) - self.autoReplaceForm.addWidget(QLabel("Auto-replace:"), 1, 0) - self.autoReplaceForm.addWidget(self.autoReplaceMain, 1, 1) - self.autoReplaceForm.addWidget(QLabel("\u2192 Single quotes"), 2, 0) - self.autoReplaceForm.addWidget(self.autoReplaceSQ, 2, 1) - self.autoReplaceForm.addWidget(QLabel("\u2192 Double quotes"), 3, 0) - self.autoReplaceForm.addWidget(self.autoReplaceDQ, 3, 1) - self.autoReplaceForm.addWidget(QLabel("\u2192 Hyphens with dash"), 4, 0) - self.autoReplaceForm.addWidget(self.autoReplaceDash, 4, 1) - self.autoReplaceForm.addWidget(QLabel("\u2192 Dots with ellipsis"), 5, 0) - self.autoReplaceForm.addWidget(self.autoReplaceDots, 5, 1) - self.autoReplaceForm.setColumnStretch(2, 1) - self.autoReplaceForm.setRowStretch(6, 1) - # Quote Style self.quoteStyle = QGroupBox("Quotation Style", self) self.quoteStyleForm = QGridLayout(self) @@ -678,24 +710,8 @@ class GuiConfigEditEditor(QWidget): self.quoteStyleForm.setColumnStretch(4, 1) self.quoteStyleForm.setRowStretch(4, 1) - # # Writing Guides - # self.showGuides = QGroupBox("Writing Guides", self) - # self.showGuidesForm = QGridLayout(self) - # self.showGuides.setLayout(self.showGuidesForm) - - # self.showTabsNSpaces = QCheckBox("Show tabs and spaces",self) - # self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) - - # self.showLineEndings = QCheckBox("Show line endings",self) - # self.showLineEndings.setChecked(self.mainConf.showLineEndings) - - # self.showGuidesForm.addWidget(self.showTabsNSpaces, 0, 0) - # self.showGuidesForm.addWidget(self.showLineEndings, 1, 0) - # Assemble - self.outerBox.addWidget(self.autoReplace, 3, 0, 2, 1) self.outerBox.addWidget(self.quoteStyle, 2, 1, 2, 1) - # self.outerBox.addWidget(self.showGuides, 4, 1) self.outerBox.setColumnStretch(2, 1) self.outerBox.setRowStretch(5, 1) self.setLayout(self.outerBox) @@ -706,20 +722,6 @@ class GuiConfigEditEditor(QWidget): validEntries = True - autoSelect = self.autoSelect.isChecked() - doReplace = self.autoReplaceMain.isChecked() - doReplaceSQuote = self.autoReplaceSQ.isChecked() - doReplaceDQuote = self.autoReplaceDQ.isChecked() - doReplaceDash = self.autoReplaceDash.isChecked() - doReplaceDots = self.autoReplaceDash.isChecked() - - self.mainConf.autoSelect = autoSelect - self.mainConf.doReplace = doReplace - self.mainConf.doReplaceSQuote = doReplaceSQuote - self.mainConf.doReplaceDQuote = doReplaceDQuote - self.mainConf.doReplaceDash = doReplaceDash - self.mainConf.doReplaceDots = doReplaceDots - fmtSingleQuotesO = self.quoteSingleStyleO.text() fmtSingleQuotesC = self.quoteSingleStyleC.text() fmtDoubleQuotesO = self.quoteDoubleStyleO.text() @@ -757,12 +759,6 @@ class GuiConfigEditEditor(QWidget): ) validEntries = False - # showTabsNSpaces = self.showTabsNSpaces.isChecked() - # showLineEndings = self.showLineEndings.isChecked() - - # self.mainConf.showTabsNSpaces = showTabsNSpaces - # self.mainConf.showLineEndings = showLineEndings - self.mainConf.confChanged = True return validEntries, False From c1c67f026b7723f4126c6e02ff933f0014a482fc Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 19:52:54 +0200 Subject: [PATCH 08/10] Finished the last tab of the config editor --- nw/gui/dialogs/configeditor.py | 268 +++++++++++++++++---------------- 1 file changed, 141 insertions(+), 127 deletions(-) diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index 5c40b8ca..75c29ab1 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -63,14 +63,14 @@ class GuiConfigEditor(QDialog): self.tabGeneral = GuiConfigEditGeneralTab(self.theParent) self.tabLayout = GuiConfigEditLayoutTab(self.theParent) self.tabEditing = GuiConfigEditEditingTab(self.theParent) - self.tabEditor = GuiConfigEditEditor(self.theParent) + self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(600) self.tabWidget.addTab(self.tabGeneral, "General") self.tabWidget.addTab(self.tabLayout, "Layout") self.tabWidget.addTab(self.tabEditing, "Editing") - self.tabWidget.addTab(self.tabEditor, "Editor") + self.tabWidget.addTab(self.tabAutoRep, "Auto-Replace") self.setLayout(self.outerBox) self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) @@ -112,7 +112,7 @@ class GuiConfigEditor(QDialog): validEntries &= retA needsRestart |= retB - retA, retB = self.tabEditor.saveValues() + retA, retB = self.tabAutoRep.saveValues() validEntries &= retA needsRestart |= retB @@ -120,7 +120,7 @@ class GuiConfigEditor(QDialog): msgBox = QMessageBox() msgBox.information( self, "Preferences", - "Some changes will not be applied until
%s has been restarted." % nw.__package__ + "Some changes will not be applied until
%s has been restarted" % nw.__package__ ) if validEntries: @@ -183,7 +183,7 @@ class GuiConfigEditGeneralTab(QWidget): self.mainForm.addRow( "Prefer icons for dark backgrounds", self.preferDarkIcons, - "May improve the look of icons on dark themes." + "May improve the look of icons on dark themes" ) # AutoSave Settings @@ -233,7 +233,7 @@ class GuiConfigEditGeneralTab(QWidget): self.mainForm.addRow( "Run backup when closing project", self.backupOnClose, - "This option can be overridden in project settings." + "This option can be overridden in project settings" ) ## Ask before backup @@ -332,7 +332,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Font family", self.textStyleFont, - "For the document editor and viewer." + "For the document editor and viewer" ) self.textStyleSize = QSpinBox(self) @@ -377,7 +377,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Disable maximum text width in Normal mode", self.textFlowFixed, - "Only fixed margins are applied to the document." + "Only fixed margins are applied to the document" ) self.textJustify = QSwitch() @@ -395,7 +395,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Document text margin", self.textMargin, - "The minimum horizontal text margin if max with is enabled.", + "The minimum horizontal text margin if max with is enabled", theUnit="px" ) @@ -407,7 +407,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Editor tab width", self.tabWidth, - "This feature requires Qt 5.9 or later.", + "This feature requires Qt 5.9 or later", theUnit="px" ) @@ -503,7 +503,7 @@ class GuiConfigEditEditingTab(QWidget): self.mainForm.addRow( "Spell check provider", self.spellToolList, - "Note that the internal spell check tool is quite slow." + "Note that the internal spell check tool is quite slow" ) self.mainForm.addRow( "Spell check language", @@ -518,63 +518,10 @@ class GuiConfigEditEditingTab(QWidget): self.mainForm.addRow( "Big document limit", self.bigDocLimit, - "Disables full spell checking over the size limit.", + "Disables full spell checking over the size limit", theUnit="kb" ) - # Automatic Features - # ================== - self.mainForm.addGroupLabel("Automatic Features") - - self.autoSelect = QSwitch() - self.autoSelect.setChecked(self.mainConf.autoSelect) - self.mainForm.addRow( - "Auto-select word under cursor", - self.autoSelect, - "Apply formatting to word under cursor if no selection is made." - ) - - self.autoReplaceMain = QSwitch() - self.autoReplaceMain.setChecked(self.mainConf.doReplace) - self.autoReplaceMain.toggled.connect(self._toggleAutoReplaceMain) - self.mainForm.addRow( - "Auto-replace text as you type", - self.autoReplaceMain, - "Apply formatting to word under cursor if no selection is made." - ) - - self.autoReplaceSQ = QSwitch() - self.autoReplaceSQ.setChecked(self.mainConf.doReplaceSQuote) - self.mainForm.addRow( - "Auto-replace single quotes", - self.autoReplaceSQ, - "The feature will try to guess opening or closing symbol." - ) - - self.autoReplaceDQ = QSwitch() - self.autoReplaceDQ.setChecked(self.mainConf.doReplaceDQuote) - self.mainForm.addRow( - "Auto-replace double quotes", - self.autoReplaceDQ, - "The feature will try to guess opening or closing symbol." - ) - - self.autoReplaceDash = QSwitch() - self.autoReplaceDash.setChecked(self.mainConf.doReplaceDash) - self.mainForm.addRow( - "Auto-replace dashes", - self.autoReplaceDash, - "Auto-replace double and triple hyphens with short and long dash." - ) - - self.autoReplaceDots = QSwitch() - self.autoReplaceDots.setChecked(self.mainConf.doReplaceDots) - self.mainForm.addRow( - "Auto-replace dots", - self.autoReplaceDots, - "Auto-replace three dots with ellipsis." - ) - return def saveValues(self): @@ -582,44 +529,18 @@ class GuiConfigEditEditingTab(QWidget): validEntries = True needsRestart = False - spellTool = self.spellToolList.currentData() - spellLanguage = self.spellLangList.currentData() - bigDocLimit = self.bigDocLimit.value() - autoSelect = self.autoSelect.isChecked() - doReplace = self.autoReplaceMain.isChecked() - doReplaceSQuote = self.autoReplaceSQ.isChecked() - doReplaceDQuote = self.autoReplaceDQ.isChecked() - doReplaceDash = self.autoReplaceDash.isChecked() - doReplaceDots = self.autoReplaceDots.isChecked() + spellTool = self.spellToolList.currentData() + spellLanguage = self.spellLangList.currentData() + bigDocLimit = self.bigDocLimit.value() - self.mainConf.spellTool = spellTool - self.mainConf.spellLanguage = spellLanguage - self.mainConf.bigDocLimit = bigDocLimit - self.mainConf.autoSelect = autoSelect - self.mainConf.doReplace = doReplace - self.mainConf.doReplaceSQuote = doReplaceSQuote - self.mainConf.doReplaceDQuote = doReplaceDQuote - self.mainConf.doReplaceDash = doReplaceDash - self.mainConf.doReplaceDots = doReplaceDots + self.mainConf.spellTool = spellTool + self.mainConf.spellLanguage = spellLanguage + self.mainConf.bigDocLimit = bigDocLimit self.mainConf.confChanged = True return validEntries, needsRestart - ## - # Slots - ## - - def _toggleAutoReplaceMain(self, theState): - """Enables or disables switches controlled by the main auto - replace switch. - """ - self.autoReplaceSQ.setEnabled(theState) - self.autoReplaceDQ.setEnabled(theState) - self.autoReplaceDash.setEnabled(theState) - self.autoReplaceDots.setEnabled(theState) - return - ## # Internal Functions ## @@ -659,62 +580,124 @@ class GuiConfigEditEditingTab(QWidget): # END Class GuiConfigEditEditingTab -class GuiConfigEditEditor(QWidget): +class GuiConfigEditAutoReplaceTab(QWidget): def __init__(self, theParent): QWidget.__init__(self, theParent) self.mainConf = nw.CONFIG self.theParent = theParent - self.outerBox = QGridLayout() + self.theTheme = theParent.theTheme - # Quote Style - self.quoteStyle = QGroupBox("Quotation Style", self) - self.quoteStyleForm = QGridLayout(self) - self.quoteStyle.setLayout(self.quoteStyleForm) + # The Form + self.mainForm = QConfigLayout() + self.mainForm.setHelpTextStyle(self.theTheme.helpText) + self.setLayout(self.mainForm) + + # Automatic Features + # ================== + self.mainForm.addGroupLabel("Automatic Features") + + self.autoSelect = QSwitch() + self.autoSelect.setChecked(self.mainConf.autoSelect) + self.mainForm.addRow( + "Auto-select word under cursor", + self.autoSelect, + "Apply formatting to word under cursor if no selection is made" + ) + + self.autoReplaceMain = QSwitch() + self.autoReplaceMain.setChecked(self.mainConf.doReplace) + self.autoReplaceMain.toggled.connect(self._toggleAutoReplaceMain) + self.mainForm.addRow( + "Auto-replace text as you type", + self.autoReplaceMain, + "Apply formatting to word under cursor if no selection is made" + ) + + # Auto-Replace + # ============ + self.mainForm.addGroupLabel("Replace as You Type") + + self.autoReplaceSQ = QSwitch() + self.autoReplaceSQ.setChecked(self.mainConf.doReplaceSQuote) + self.mainForm.addRow( + "Auto-replace single quotes", + self.autoReplaceSQ, + "The feature will try to guess opening or closing single quote" + ) + + self.autoReplaceDQ = QSwitch() + self.autoReplaceDQ.setChecked(self.mainConf.doReplaceDQuote) + self.mainForm.addRow( + "Auto-replace double quotes", + self.autoReplaceDQ, + "The feature will try to guess opening or closing quote quote" + ) + + self.autoReplaceDash = QSwitch() + self.autoReplaceDash.setChecked(self.mainConf.doReplaceDash) + self.mainForm.addRow( + "Auto-replace dashes", + self.autoReplaceDash, + "Auto-replace double and triple hyphens with short and long dash" + ) + + self.autoReplaceDots = QSwitch() + self.autoReplaceDots.setChecked(self.mainConf.doReplaceDots) + self.mainForm.addRow( + "Auto-replace dots", + self.autoReplaceDots, + "Auto-replace three dots with ellipsis" + ) + + # Quotation Style + # =============== + self.mainForm.addGroupLabel("Quotation Style") self.quoteSingleStyleO = QLineEdit() self.quoteSingleStyleO.setMaxLength(1) - self.quoteSingleStyleO.setFixedWidth(30) + self.quoteSingleStyleO.setFixedWidth(40) self.quoteSingleStyleO.setAlignment(Qt.AlignCenter) self.quoteSingleStyleO.setText(self.mainConf.fmtSingleQuotes[0]) + self.mainForm.addRow( + "Single quote open style", + self.quoteSingleStyleO, + "Auto-replaces apostrophe before words" + ) self.quoteSingleStyleC = QLineEdit() self.quoteSingleStyleC.setMaxLength(1) - self.quoteSingleStyleC.setFixedWidth(30) + self.quoteSingleStyleC.setFixedWidth(40) self.quoteSingleStyleC.setAlignment(Qt.AlignCenter) self.quoteSingleStyleC.setText(self.mainConf.fmtSingleQuotes[1]) + self.mainForm.addRow( + "Single quote close style", + self.quoteSingleStyleC, + "Auto-replaces apostrophe after words" + ) self.quoteDoubleStyleO = QLineEdit() self.quoteDoubleStyleO.setMaxLength(1) - self.quoteDoubleStyleO.setFixedWidth(30) + self.quoteDoubleStyleO.setFixedWidth(40) self.quoteDoubleStyleO.setAlignment(Qt.AlignCenter) self.quoteDoubleStyleO.setText(self.mainConf.fmtDoubleQuotes[0]) + self.mainForm.addRow( + "Double quote open style", + self.quoteDoubleStyleO, + "Auto-replaces straight quotes before words" + ) self.quoteDoubleStyleC = QLineEdit() self.quoteDoubleStyleC.setMaxLength(1) - self.quoteDoubleStyleC.setFixedWidth(30) + self.quoteDoubleStyleC.setFixedWidth(40) self.quoteDoubleStyleC.setAlignment(Qt.AlignCenter) self.quoteDoubleStyleC.setText(self.mainConf.fmtDoubleQuotes[1]) - - self.quoteStyleForm.addWidget(QLabel("Single Quotes"), 0, 0, 1, 3) - self.quoteStyleForm.addWidget(QLabel("Open"), 1, 0) - self.quoteStyleForm.addWidget(self.quoteSingleStyleO, 1, 1) - self.quoteStyleForm.addWidget(QLabel("Close"), 1, 2) - self.quoteStyleForm.addWidget(self.quoteSingleStyleC, 1, 3) - self.quoteStyleForm.addWidget(QLabel("Double Quotes"), 2, 0, 1, 3) - self.quoteStyleForm.addWidget(QLabel("Open"), 3, 0) - self.quoteStyleForm.addWidget(self.quoteDoubleStyleO, 3, 1) - self.quoteStyleForm.addWidget(QLabel("Close"), 3, 2) - self.quoteStyleForm.addWidget(self.quoteDoubleStyleC, 3, 3) - self.quoteStyleForm.setColumnStretch(4, 1) - self.quoteStyleForm.setRowStretch(4, 1) - - # Assemble - self.outerBox.addWidget(self.quoteStyle, 2, 1, 2, 1) - self.outerBox.setColumnStretch(2, 1) - self.outerBox.setRowStretch(5, 1) - self.setLayout(self.outerBox) + self.mainForm.addRow( + "Double quote close style", + self.quoteDoubleStyleC, + "Auto-replaces straight quotes after words" + ) return @@ -722,6 +705,20 @@ class GuiConfigEditEditor(QWidget): validEntries = True + autoSelect = self.autoSelect.isChecked() + doReplace = self.autoReplaceMain.isChecked() + doReplaceSQuote = self.autoReplaceSQ.isChecked() + doReplaceDQuote = self.autoReplaceDQ.isChecked() + doReplaceDash = self.autoReplaceDash.isChecked() + doReplaceDots = self.autoReplaceDots.isChecked() + + self.mainConf.autoSelect = autoSelect + self.mainConf.doReplace = doReplace + self.mainConf.doReplaceSQuote = doReplaceSQuote + self.mainConf.doReplaceDQuote = doReplaceDQuote + self.mainConf.doReplaceDash = doReplaceDash + self.mainConf.doReplaceDots = doReplaceDots + fmtSingleQuotesO = self.quoteSingleStyleO.text() fmtSingleQuotesC = self.quoteSingleStyleC.text() fmtDoubleQuotesO = self.quoteDoubleStyleO.text() @@ -763,15 +760,32 @@ class GuiConfigEditEditor(QWidget): return validEntries, False + ## + # Slots + ## + + def _toggleAutoReplaceMain(self, theState): + """Enables or disables switches controlled by the main auto + replace switch. + """ + self.autoReplaceSQ.setEnabled(theState) + self.autoReplaceDQ.setEnabled(theState) + self.autoReplaceDash.setEnabled(theState) + self.autoReplaceDots.setEnabled(theState) + return + ## # Internal Functions ## def _checkQuoteSymbol(self, toCheck): + """Check that the quote symbols entered are in nwQuotes and is + therefore a valid quote symbol for this app. + """ if len(toCheck) != 1: return False if toCheck in nwQuotes.SYMBOLS: return True return False -# END Class GuiConfigEditEditor +# END Class GuiConfigEditAutoReplaceTab From cbf0c265b9cbbafcddcf196786d4b65e37c4457b Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 20:04:51 +0200 Subject: [PATCH 09/10] Connected the full path in header option to the config gui --- nw/gui/dialogs/configeditor.py | 52 ++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index 75c29ab1..821a9075 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -149,9 +149,9 @@ class GuiConfigEditGeneralTab(QWidget): self.mainForm.setHelpTextStyle(self.theTheme.helpText) self.setLayout(self.mainForm) - # GUI Settings - # ============ - self.mainForm.addGroupLabel("GUI") + # Look and Feel + # ============= + self.mainForm.addGroupLabel("Look and Feel") ## Select Theme self.selectTheme = QComboBox() @@ -163,7 +163,11 @@ class GuiConfigEditGeneralTab(QWidget): if themeIdx != -1: self.selectTheme.setCurrentIndex(themeIdx) - self.mainForm.addRow("Colour theme", self.selectTheme) + self.mainForm.addRow( + "Main GUI theme", + self.selectTheme, + "Changing this requires restarting %s" % nw.__package__ + ) ## Syntax Highlighting self.selectSyntax = QComboBox() @@ -175,7 +179,10 @@ class GuiConfigEditGeneralTab(QWidget): if syntaxIdx != -1: self.selectSyntax.setCurrentIndex(syntaxIdx) - self.mainForm.addRow("Syntax highlight theme", self.selectSyntax) + self.mainForm.addRow( + "Syntax highlight theme", + self.selectSyntax + ) ## Dark Icons self.preferDarkIcons = QSwitch() @@ -186,10 +193,22 @@ class GuiConfigEditGeneralTab(QWidget): "May improve the look of icons on dark themes" ) + # GUI Settings + # ============ + self.mainForm.addGroupLabel("GUI Settings") + + self.showFullPath = QSwitch() + self.showFullPath.setChecked(self.mainConf.showFullPath) + self.mainForm.addRow( + "Show full path in document header", + self.showFullPath + ) + # AutoSave Settings # ================= self.mainForm.addGroupLabel("Automatic Save") + ## Document Save Timer self.autoSaveDoc = QSpinBox(self) self.autoSaveDoc.setMinimum(5) self.autoSaveDoc.setMaximum(600) @@ -201,6 +220,7 @@ class GuiConfigEditGeneralTab(QWidget): theUnit="seconds" ) + ## Project Save Timer self.autoSaveProj = QSpinBox(self) self.autoSaveProj.setMinimum(5) self.autoSaveProj.setMaximum(600) @@ -254,6 +274,7 @@ class GuiConfigEditGeneralTab(QWidget): guiTheme = self.selectTheme.currentData() guiSyntax = self.selectSyntax.currentData() guiDark = self.preferDarkIcons.isChecked() + showFullPath = self.showFullPath.isChecked() autoSaveDoc = self.autoSaveDoc.value() autoSaveProj = self.autoSaveProj.value() backupPath = self.backupPath @@ -266,6 +287,7 @@ class GuiConfigEditGeneralTab(QWidget): self.mainConf.guiTheme = guiTheme self.mainConf.guiSyntax = guiSyntax self.mainConf.guiDark = guiDark + self.mainConf.showFullPath = showFullPath self.mainConf.autoSaveDoc = autoSaveDoc self.mainConf.autoSaveProj = autoSaveProj self.mainConf.backupPath = backupPath @@ -326,6 +348,7 @@ class GuiConfigEditLayoutTab(QWidget): # ========== self.mainForm.addGroupLabel("Text Style") + ## Font Family self.textStyleFont = QFontComboBox() self.textStyleFont.setMaximumWidth(200) self.textStyleFont.setCurrentFont(QFont(self.mainConf.textFont)) @@ -335,6 +358,7 @@ class GuiConfigEditLayoutTab(QWidget): "For the document editor and viewer" ) + ## Font Size self.textStyleSize = QSpinBox(self) self.textStyleSize.setMinimum(5) self.textStyleSize.setMaximum(120) @@ -350,6 +374,7 @@ class GuiConfigEditLayoutTab(QWidget): # ========= self.mainForm.addGroupLabel("Text Flow") + ## Max Text Width in Normal Mode self.textFlowMax = QSpinBox(self) self.textFlowMax.setMinimum(300) self.textFlowMax.setMaximum(10000) @@ -361,6 +386,7 @@ class GuiConfigEditLayoutTab(QWidget): theUnit="px" ) + ## Max Text Width in Zen Mode self.zenDocWidth = QSpinBox(self) self.zenDocWidth.setMinimum(300) self.zenDocWidth.setMaximum(10000) @@ -372,6 +398,7 @@ class GuiConfigEditLayoutTab(QWidget): theUnit="px" ) + ## Document Fixed Width self.textFlowFixed = QSwitch() self.textFlowFixed.setChecked(not self.mainConf.textFixedW) self.mainForm.addRow( @@ -380,6 +407,7 @@ class GuiConfigEditLayoutTab(QWidget): "Only fixed margins are applied to the document" ) + ## Justify Text self.textJustify = QSwitch() self.textJustify.setChecked(self.mainConf.textFixedW) self.mainForm.addRow( @@ -387,6 +415,7 @@ class GuiConfigEditLayoutTab(QWidget): self.textJustify ) + ## Document Margins self.textMargin = QSpinBox(self) self.textMargin.setMinimum(0) self.textMargin.setMaximum(900) @@ -399,6 +428,7 @@ class GuiConfigEditLayoutTab(QWidget): theUnit="px" ) + ## Tab Width self.tabWidth = QSpinBox(self) self.tabWidth.setMinimum(0) self.tabWidth.setMaximum(200) @@ -415,6 +445,7 @@ class GuiConfigEditLayoutTab(QWidget): # ============== self.mainForm.addGroupLabel("Writing Guides") + ## Show Tabs and Spaces self.showTabsNSpaces = QSwitch() self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) self.mainForm.addRow( @@ -422,6 +453,7 @@ class GuiConfigEditLayoutTab(QWidget): self.showTabsNSpaces ) + ## Show Line Endings self.showLineEndings = QSwitch() self.showLineEndings.setChecked(self.mainConf.showLineEndings) self.mainForm.addRow( @@ -482,6 +514,7 @@ class GuiConfigEditEditingTab(QWidget): # ============== self.mainForm.addGroupLabel("Spell Checking") + ## Spell Check Provider and Language self.spellLangList = QComboBox(self) self.spellToolList = QComboBox(self) self.spellToolList.addItem("Internal (difflib)", NWSpellCheck.SP_INTERNAL) @@ -510,6 +543,7 @@ class GuiConfigEditEditingTab(QWidget): self.spellLangList ) + ## Big Document Size Limit self.bigDocLimit = QSpinBox(self) self.bigDocLimit.setMinimum(10) self.bigDocLimit.setMaximum(10000) @@ -598,6 +632,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): # ================== self.mainForm.addGroupLabel("Automatic Features") + ## Auto-Select Word Under Cursor self.autoSelect = QSwitch() self.autoSelect.setChecked(self.mainConf.autoSelect) self.mainForm.addRow( @@ -606,6 +641,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): "Apply formatting to word under cursor if no selection is made" ) + ## Auto-Replace as You Type Main Switch self.autoReplaceMain = QSwitch() self.autoReplaceMain.setChecked(self.mainConf.doReplace) self.autoReplaceMain.toggled.connect(self._toggleAutoReplaceMain) @@ -619,6 +655,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): # ============ self.mainForm.addGroupLabel("Replace as You Type") + ## Auto-Replace Single Quotes self.autoReplaceSQ = QSwitch() self.autoReplaceSQ.setChecked(self.mainConf.doReplaceSQuote) self.mainForm.addRow( @@ -627,6 +664,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): "The feature will try to guess opening or closing single quote" ) + ## Auto-Replace Double Quotes self.autoReplaceDQ = QSwitch() self.autoReplaceDQ.setChecked(self.mainConf.doReplaceDQuote) self.mainForm.addRow( @@ -635,6 +673,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): "The feature will try to guess opening or closing quote quote" ) + ## Auto-Replace Hyphens self.autoReplaceDash = QSwitch() self.autoReplaceDash.setChecked(self.mainConf.doReplaceDash) self.mainForm.addRow( @@ -643,6 +682,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): "Auto-replace double and triple hyphens with short and long dash" ) + ## Auto-Replace Dots self.autoReplaceDots = QSwitch() self.autoReplaceDots.setChecked(self.mainConf.doReplaceDots) self.mainForm.addRow( @@ -655,6 +695,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): # =============== self.mainForm.addGroupLabel("Quotation Style") + ## Single Quote Style self.quoteSingleStyleO = QLineEdit() self.quoteSingleStyleO.setMaxLength(1) self.quoteSingleStyleO.setFixedWidth(40) @@ -677,6 +718,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): "Auto-replaces apostrophe after words" ) + ## Double Quote Style self.quoteDoubleStyleO = QLineEdit() self.quoteDoubleStyleO.setMaxLength(1) self.quoteDoubleStyleO.setFixedWidth(40) From 9daa77486c426d46cee5ad162c7a5f3cbdb4de00 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 3 May 2020 20:16:13 +0200 Subject: [PATCH 10/10] Remove some unneeded imports --- nw/additions/qconfiglayout.py | 2 +- nw/gui/dialogs/configeditor.py | 6 +++--- nw/gui/elements/doctitlebar.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nw/additions/qconfiglayout.py b/nw/additions/qconfiglayout.py index 0e413da6..7f706559 100644 --- a/nw/additions/qconfiglayout.py +++ b/nw/additions/qconfiglayout.py @@ -31,7 +31,7 @@ import nw from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor, QPalette from PyQt5.QtWidgets import ( - QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QLayout + QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout ) from nw.constants import nwUnicode diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index 821a9075..0ffe6700 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -33,9 +33,9 @@ from os import path from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont from PyQt5.QtWidgets import ( - QDialog, QHBoxLayout, QVBoxLayout, QLineEdit, QLabel, QWidget, QTabWidget, - QDialogButtonBox, QSpinBox, QGroupBox, QComboBox, QMessageBox, QCheckBox, - QGridLayout, QFontComboBox, QPushButton, QFileDialog, QFormLayout + QDialog, QWidget, QHBoxLayout, QVBoxLayout, QTabWidget, QComboBox, QSpinBox, + QPushButton, QFontComboBox, QLineEdit, QDialogButtonBox, QMessageBox, + QFileDialog ) from nw.additions import QSwitch, QConfigLayout diff --git a/nw/gui/elements/doctitlebar.py b/nw/gui/elements/doctitlebar.py index b8d5d739..7ecfc417 100644 --- a/nw/gui/elements/doctitlebar.py +++ b/nw/gui/elements/doctitlebar.py @@ -30,7 +30,7 @@ import nw from PyQt5.QtCore import Qt from PyQt5.QtGui import QPalette, QColor -from PyQt5.QtWidgets import QLabel, QFrame, QStyle +from PyQt5.QtWidgets import QLabel, QFrame from nw.constants import nwUnicode