From bd9b40a1cad0dcac02fe3c035a1bb6570d1c14a7 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 12:56:58 +0200
Subject: [PATCH 1/7] Added PagedDialog base class, and applied it to project
settings
---
nw/gui/__init__.py | 6 ---
nw/gui/additions/__init__.py | 2 +
nw/gui/additions/pageddialog.py | 65 +++++++++++++++++++++++++++++++++
nw/gui/dialogs/projecteditor.py | 31 +++++-----------
4 files changed, 77 insertions(+), 27 deletions(-)
create mode 100644 nw/gui/additions/pageddialog.py
diff --git a/nw/gui/__init__.py b/nw/gui/__init__.py
index c209b8d8..74706a6d 100644
--- a/nw/gui/__init__.py
+++ b/nw/gui/__init__.py
@@ -7,10 +7,6 @@ from nw.gui.mainmenu import GuiMainMenu
from nw.gui.statusbar import GuiMainStatus
from nw.gui.theme import GuiTheme
-# Qt Additions
-from nw.gui.additions.qconfiglayout import QConfigLayout
-from nw.gui.additions.qswitch import QSwitch
-
# Dialogs
from nw.gui.dialogs.configeditor import GuiConfigEditor
from nw.gui.dialogs.docmerge import GuiDocMerge
@@ -42,8 +38,6 @@ __all__ = [
"GuiMainMenu",
"GuiMainStatus",
"GuiTheme",
- "QConfigLayout",
- "QSwitch",
"GuiConfigEditor",
"GuiDocMerge",
"GuiDocSplit",
diff --git a/nw/gui/additions/__init__.py b/nw/gui/additions/__init__.py
index 04f5e25a..32af81f6 100644
--- a/nw/gui/additions/__init__.py
+++ b/nw/gui/additions/__init__.py
@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
+from nw.gui.additions.pageddialog import PagedDialog
from nw.gui.additions.qconfiglayout import QConfigLayout
from nw.gui.additions.qswitch import QSwitch
__all__ = [
+ "PagedDialog",
"QConfigLayout",
"QSwitch",
]
diff --git a/nw/gui/additions/pageddialog.py b/nw/gui/additions/pageddialog.py
new file mode 100644
index 00000000..5f06c84e
--- /dev/null
+++ b/nw/gui/additions/pageddialog.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+"""novelWriter Paged Dialog
+
+ novelWriter – Paged Dialog
+============================
+ A custom QDialog with a built-in QTabWidget and vertical tabs.
+
+ File History:
+ Created: 2020-05-17 [0.5.1]
+
+ 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 .
+"""
+
+import logging
+import nw
+
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import (
+ QDialog, QHBoxLayout, QVBoxLayout, QTabWidget
+)
+
+from nw.constants import nwUnicode
+
+logger = logging.getLogger(__name__)
+
+class PagedDialog(QDialog):
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+
+ self._outerBox = QVBoxLayout()
+ self._innerBox = QHBoxLayout()
+ self._navBox = QVBoxLayout()
+ self._tabBox = QTabWidget()
+
+ self._outerBox.addLayout(self._innerBox)
+ self._innerBox.addLayout(self._navBox)
+ self._innerBox.addWidget(self._tabBox)
+ self.setLayout(self._outerBox)
+
+ return
+
+ def addPage(self, tabWidget, tabLabel):
+ self._tabBox.addTab(tabWidget, tabLabel)
+ return
+
+ def addControls(self, buttonBar):
+ self._outerBox.addWidget(buttonBar)
+ return
+
+# END Class PagedDialog
diff --git a/nw/gui/dialogs/projecteditor.py b/nw/gui/dialogs/projecteditor.py
index ff6171cd..9c5b4ba4 100644
--- a/nw/gui/dialogs/projecteditor.py
+++ b/nw/gui/dialogs/projecteditor.py
@@ -38,13 +38,14 @@ from PyQt5.QtWidgets import (
)
from nw.constants import nwAlert
+from nw.gui.additions import PagedDialog
logger = logging.getLogger(__name__)
-class GuiProjectEditor(QDialog):
+class GuiProjectEditor(PagedDialog):
def __init__(self, theParent, theProject):
- QDialog.__init__(self, theParent)
+ PagedDialog.__init__(self, theParent)
logger.debug("Initialising ProjectEditor ...")
@@ -52,35 +53,23 @@ class GuiProjectEditor(QDialog):
self.theParent = theParent
self.theProject = theProject
- self.outerBox = QHBoxLayout()
- self.innerBox = QVBoxLayout()
-
- self.setWindowTitle("Project Settings")
- self.guiDeco = self.theParent.theTheme.loadDecoration("settings", (64,64))
- self.outerBox.setSpacing(16)
-
- self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop)
- self.outerBox.addLayout(self.innerBox)
- self.setLayout(self.outerBox)
-
self.theProject.countStatus()
+ self.setWindowTitle("Project Settings")
+
self.tabMain = GuiProjectEditMain(self.theParent, self.theProject)
self.tabStatus = GuiProjectEditStatus(self.theParent, self.theProject.statusItems)
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject.importItems)
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
- self.tabWidget = QTabWidget()
- self.tabWidget.addTab(self.tabMain, "Settings")
- self.tabWidget.addTab(self.tabStatus, "Status")
- self.tabWidget.addTab(self.tabImport, "Importance")
- self.tabWidget.addTab(self.tabReplace,"Auto-Replace")
+ self.addPage(self.tabMain, "Settings")
+ self.addPage(self.tabStatus, "Status")
+ self.addPage(self.tabImport, "Importance")
+ self.addPage(self.tabReplace,"Auto-Replace")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
-
- self.innerBox.addWidget(self.tabWidget)
- self.innerBox.addWidget(self.buttonBox)
+ self.addControls(self.buttonBox)
self.show()
From 80872fecebf34a177843a313e46c1b7f24b816d2 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 16:08:58 +0200
Subject: [PATCH 2/7] Paged dialog with vertical tabs now working
---
nw/gui/additions/pageddialog.py | 79 ++++++++++++++++++++++++++++-----
nw/gui/dialogs/configeditor.py | 28 ++++--------
nw/gui/dialogs/projecteditor.py | 8 ++--
3 files changed, 79 insertions(+), 36 deletions(-)
diff --git a/nw/gui/additions/pageddialog.py b/nw/gui/additions/pageddialog.py
index 5f06c84e..40ba8656 100644
--- a/nw/gui/additions/pageddialog.py
+++ b/nw/gui/additions/pageddialog.py
@@ -28,9 +28,11 @@
import logging
import nw
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QRect, QPoint
+from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QTabWidget
+ QWidget, QDialog, QHBoxLayout, QVBoxLayout, QTabWidget, QTabBar,
+ QStylePainter, QStyleOptionTab, QStyle, QLabel
)
from nw.constants import nwUnicode
@@ -40,26 +42,79 @@ logger = logging.getLogger(__name__)
class PagedDialog(QDialog):
def __init__(self, parent=None):
- super().__init__(parent=parent)
+ QDialog.__init__(self, parent=parent)
- self._outerBox = QVBoxLayout()
- self._innerBox = QHBoxLayout()
- self._navBox = QVBoxLayout()
- self._tabBox = QTabWidget()
+ self._outerBox = QVBoxLayout()
+ self._buttonBox = QHBoxLayout()
+ self._tabBox = QTabWidget()
- self._outerBox.addLayout(self._innerBox)
- self._innerBox.addLayout(self._navBox)
- self._innerBox.addWidget(self._tabBox)
+ self._tabBar = VerticalTabBar(self)
+ self._tabBox.setTabBar(self._tabBar)
+ self._tabBox.setTabPosition(QTabWidget.West)
+ self._tabBar.setExpanding(False)
+
+ self._outerBox.addWidget(self._tabBox)
+ self._outerBox.addLayout(self._buttonBox)
self.setLayout(self._outerBox)
+ # Default Margins
+ qM = self._outerBox.contentsMargins()
+ mL = qM.left()
+ mR = qM.right()
+ mT = qM.top()
+ mB = qM.bottom()
+
+ self.setContentsMargins(0, 0, 0, 0)
+ self._outerBox.setContentsMargins(0, 0, 0, mB)
+ self._buttonBox.setContentsMargins(mL, 0, mR, 0)
+ self._outerBox.setSpacing(mT)
+
return
- def addPage(self, tabWidget, tabLabel):
+ def addTab(self, tabWidget, tabLabel):
self._tabBox.addTab(tabWidget, tabLabel)
return
def addControls(self, buttonBar):
- self._outerBox.addWidget(buttonBar)
+ self._buttonBox.addWidget(buttonBar)
return
# END Class PagedDialog
+
+class VerticalTabBar(QTabBar):
+
+ def __init__(self, parent=None):
+ QTabBar.__init__(self, parent=parent)
+ return
+
+ def tabSizeHint(self, theIndex):
+ tSize = QTabBar.tabSizeHint(self, theIndex)
+ tSize.transpose()
+ return tSize
+
+ def paintEvent(self, theEvent):
+
+ pObj = QStylePainter(self)
+ oObj = QStyleOptionTab()
+
+ for i in range(self.count()):
+ self.initStyleOption(oObj, i)
+ pObj.drawControl(QStyle.CE_TabBarTabShape, oObj)
+ pObj.save()
+
+ oSize = oObj.rect.size()
+ oSize.transpose()
+ oRect = QRect(QPoint(), oSize)
+ oRect.moveCenter(oObj.rect.center())
+ oObj.rect = oRect
+
+ oCenter = self.tabRect(i).center()
+ pObj.translate(oCenter)
+ pObj.rotate(90)
+ pObj.translate(-oCenter)
+ pObj.drawControl(QStyle.CE_TabBarTabLabel, oObj)
+ pObj.restore()
+
+ return
+
+# END Class VerticalTabBar
diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py
index da3158c0..61726a93 100644
--- a/nw/gui/dialogs/configeditor.py
+++ b/nw/gui/dialogs/configeditor.py
@@ -38,51 +38,39 @@ from PyQt5.QtWidgets import (
QFileDialog
)
-from nw.gui.additions import QSwitch, QConfigLayout
+from nw.gui.additions import QSwitch, QConfigLayout, PagedDialog
from nw.core import NWSpellCheck, NWSpellSimple, NWSpellEnchant
from nw.constants import nwAlert, nwQuotes
logger = logging.getLogger(__name__)
-class GuiConfigEditor(QDialog):
+class GuiConfigEditor(PagedDialog):
def __init__(self, theParent, theProject):
- QDialog.__init__(self, theParent)
+ PagedDialog.__init__(self, theParent)
logger.debug("Initialising ConfigEditor ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
- self.outerBox = QHBoxLayout()
- self.innerBox = QVBoxLayout()
self.setWindowTitle("Preferences")
- self.guiDeco = self.theParent.theTheme.loadDecoration("settings", (64,64))
- self.outerBox.setSpacing(16)
-
- self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop)
- self.outerBox.addLayout(self.innerBox)
- self.setLayout(self.outerBox)
self.tabGeneral = GuiConfigEditGeneralTab(self.theParent)
self.tabLayout = GuiConfigEditLayoutTab(self.theParent)
self.tabEditing = GuiConfigEditEditingTab(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.tabAutoRep, "Auto-Replace")
+ self.addTab(self.tabGeneral, "General")
+ self.addTab(self.tabLayout, "Layout")
+ self.addTab(self.tabEditing, "Editing")
+ self.addTab(self.tabAutoRep, "Auto-Replace")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
-
- self.innerBox.addWidget(self.tabWidget)
- self.innerBox.addWidget(self.buttonBox)
+ self.addControls(self.buttonBox)
self.show()
diff --git a/nw/gui/dialogs/projecteditor.py b/nw/gui/dialogs/projecteditor.py
index 9c5b4ba4..4c425770 100644
--- a/nw/gui/dialogs/projecteditor.py
+++ b/nw/gui/dialogs/projecteditor.py
@@ -61,10 +61,10 @@ class GuiProjectEditor(PagedDialog):
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject.importItems)
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
- self.addPage(self.tabMain, "Settings")
- self.addPage(self.tabStatus, "Status")
- self.addPage(self.tabImport, "Importance")
- self.addPage(self.tabReplace,"Auto-Replace")
+ self.addTab(self.tabMain, "Settings")
+ self.addTab(self.tabStatus, "Status")
+ self.addTab(self.tabImport, "Importance")
+ self.addTab(self.tabReplace,"Auto-Replace")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self._doSave)
From c06b63211186ee40dfb489f465a2cda4b350337b Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 16:16:43 +0200
Subject: [PATCH 3/7] Import cleanup and fixed test
---
nw/gui/additions/pageddialog.py | 5 ++---
tests/test_gui.py | 4 ++--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/nw/gui/additions/pageddialog.py b/nw/gui/additions/pageddialog.py
index 40ba8656..683b62f1 100644
--- a/nw/gui/additions/pageddialog.py
+++ b/nw/gui/additions/pageddialog.py
@@ -29,10 +29,9 @@ import logging
import nw
from PyQt5.QtCore import Qt, QRect, QPoint
-from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import (
- QWidget, QDialog, QHBoxLayout, QVBoxLayout, QTabWidget, QTabBar,
- QStylePainter, QStyleOptionTab, QStyle, QLabel
+ QDialog, QHBoxLayout, QVBoxLayout, QTabWidget, QTabBar, QStyle,
+ QStylePainter, QStyleOptionTab
)
from nw.constants import nwUnicode
diff --git a/tests/test_gui.py b/tests/test_gui.py
index c32e8168..0d73f3c3 100644
--- a/tests/test_gui.py
+++ b/tests/test_gui.py
@@ -276,7 +276,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=keyDelay)
# Test Status Tab
- projEdit.tabWidget.setCurrentWidget(projEdit.tabStatus)
+ projEdit._tabBox.setCurrentWidget(projEdit.tabStatus)
projEdit.tabStatus.listBox.item(2).setSelected(True)
qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton)
qtbot.mouseClick(projEdit.tabStatus.newButton, Qt.LeftButton)
@@ -288,7 +288,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
qtbot.mouseClick(projEdit.tabStatus.saveButton, Qt.LeftButton)
# Auto-Replace Tab
- projEdit.tabWidget.setCurrentWidget(projEdit.tabReplace)
+ projEdit._tabBox.setCurrentWidget(projEdit.tabReplace)
qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton)
projEdit.tabReplace.listBox.topLevelItem(0).setSelected(True)
From 0d34a71f3cab7f2cd6cb569d58001b3faabceec3 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 16:34:51 +0200
Subject: [PATCH 4/7] Some minor cleanup in project settings and preferences
---
nw/gui/dialogs/configeditor.py | 3 ++-
nw/gui/dialogs/projecteditor.py | 48 +++++++++++++++++----------------
2 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py
index 61726a93..cd54ee28 100644
--- a/nw/gui/dialogs/configeditor.py
+++ b/nw/gui/dialogs/configeditor.py
@@ -761,6 +761,7 @@ class GuiConfigEditAutoReplaceTab(QWidget):
def saveValues(self):
validEntries = True
+ needsRestart = False
autoSelect = self.autoSelect.isChecked()
doReplace = self.autoReplaceMain.isChecked()
@@ -815,7 +816,7 @@ class GuiConfigEditAutoReplaceTab(QWidget):
self.mainConf.confChanged = True
- return validEntries, False
+ return validEntries, needsRestart
##
# Slots
diff --git a/nw/gui/dialogs/projecteditor.py b/nw/gui/dialogs/projecteditor.py
index 4c425770..1c494ac0 100644
--- a/nw/gui/dialogs/projecteditor.py
+++ b/nw/gui/dialogs/projecteditor.py
@@ -31,14 +31,14 @@ import nw
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QFormLayout, QLineEdit, QPlainTextEdit,
+ QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
QLabel, QWidget, QTabWidget, QDialogButtonBox, QListWidget, QPushButton,
QListWidgetItem, QColorDialog, QAbstractItemView, QTreeWidget, QCheckBox,
QTreeWidgetItem
)
from nw.constants import nwAlert
-from nw.gui.additions import PagedDialog
+from nw.gui.additions import QSwitch, PagedDialog
logger = logging.getLogger(__name__)
@@ -83,7 +83,7 @@ class GuiProjectEditor(PagedDialog):
projName = self.tabMain.editName.text()
bookTitle = self.tabMain.editTitle.text()
bookAuthors = self.tabMain.editAuthors.toPlainText()
- doBackup = self.tabMain.doBackup.isChecked()
+ doBackup = not self.tabMain.doBackup.isChecked()
self.theProject.setProjectName(projName)
self.theProject.setBookTitle(bookTitle)
self.theProject.setBookAuthors(bookAuthors)
@@ -119,37 +119,39 @@ class GuiProjectEditMain(QWidget):
self.theParent = theParent
self.theProject = theProject
- self.mainForm = QFormLayout()
+ self.mainForm = QGridLayout()
self.backupBox = QHBoxLayout()
- self.editName = QLineEdit()
- self.editTitle = QLineEdit()
- self.editAuthors = QPlainTextEdit()
- self.doBackup = QCheckBox(self)
+ self.editName = QLineEdit()
self.editName.setMaxLength(200)
- self.editTitle.setMaxLength(200)
-
- self.mainForm.addRow("Working Title", self.editName)
- self.mainForm.addRow("Book Title", self.editTitle)
- self.mainForm.addRow("Book Authors", self.editAuthors)
- self.mainForm.addRow(self.backupBox)
- self.backupBox.addStretch(1)
- self.backupBox.addWidget(QLabel("Backup on Close"))
- self.backupBox.addWidget(self.doBackup)
-
self.editName.setText(self.theProject.projName)
+
+ self.editTitle = QLineEdit()
+ self.editTitle.setMaxLength(200)
self.editTitle.setText(self.theProject.bookTitle)
+
+ self.editAuthors = QPlainTextEdit()
bookAuthors = ""
for bookAuthor in self.theProject.bookAuthors:
bookAuthors += bookAuthor+"\n"
self.editAuthors.setPlainText(bookAuthors)
- if self.theProject.doBackup:
- self.doBackup.setCheckState(Qt.Checked)
- else:
- self.doBackup.setCheckState(Qt.Unchecked)
+ self.editAuthors.setMaximumHeight(120)
+
+ self.doBackup = QSwitch(self)
+ self.doBackup.setChecked(not self.theProject.doBackup)
+ self.backupBox.addStretch(1)
+ self.backupBox.addWidget(QLabel("Disable backup on close"))
+ self.backupBox.addWidget(self.doBackup)
+
+ self.mainForm.addWidget(QLabel("Working title"), 0, 0, 1, 1, Qt.AlignTop)
+ self.mainForm.addWidget(self.editName, 0, 1, 1, 1, Qt.AlignTop)
+ self.mainForm.addWidget(QLabel("Book title"), 1, 0, 1, 1, Qt.AlignTop)
+ self.mainForm.addWidget(self.editTitle, 1, 1, 1, 1, Qt.AlignTop)
+ self.mainForm.addWidget(QLabel("Book authors"), 2, 0, 1, 1, Qt.AlignTop)
+ self.mainForm.addWidget(self.editAuthors, 2, 1, 1, 1, Qt.AlignTop)
+ self.mainForm.addLayout(self.backupBox, 3, 0, 1, 2, Qt.AlignTop)
self.setLayout(self.mainForm)
- self.editAuthors.setMaximumHeight(120)
return
From 6868795bc33dc9f5a024ae148e0129f326db7821 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 16:37:35 +0200
Subject: [PATCH 5/7] consistency ...
---
nw/gui/additions/pageddialog.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/nw/gui/additions/pageddialog.py b/nw/gui/additions/pageddialog.py
index 683b62f1..6e5c2e23 100644
--- a/nw/gui/additions/pageddialog.py
+++ b/nw/gui/additions/pageddialog.py
@@ -34,14 +34,12 @@ from PyQt5.QtWidgets import (
QStylePainter, QStyleOptionTab
)
-from nw.constants import nwUnicode
-
logger = logging.getLogger(__name__)
class PagedDialog(QDialog):
- def __init__(self, parent=None):
- QDialog.__init__(self, parent=parent)
+ def __init__(self, theParent=None):
+ QDialog.__init__(self, parent=theParent)
self._outerBox = QVBoxLayout()
self._buttonBox = QHBoxLayout()
@@ -82,8 +80,8 @@ class PagedDialog(QDialog):
class VerticalTabBar(QTabBar):
- def __init__(self, parent=None):
- QTabBar.__init__(self, parent=parent)
+ def __init__(self, theParent=None):
+ QTabBar.__init__(self, parent=theParent)
return
def tabSizeHint(self, theIndex):
From 7be78f6e1e7e071378eb5dc05b3a408b09bd118f Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 18:04:48 +0200
Subject: [PATCH 6/7] Cleaned up the split and merge dialogs
---
nw/assets/graphics/export.svg | 44 -----------------------------
nw/assets/graphics/merge.svg | 31 ---------------------
nw/assets/graphics/split.svg | 31 ---------------------
nw/gui/additions/__init__.py | 2 ++
nw/gui/additions/qconfiglayout.py | 32 +++++++++++++++------
nw/gui/dialogs/docmerge.py | 46 +++++++++++++++----------------
nw/gui/dialogs/docsplit.py | 44 ++++++++++++++---------------
nw/gui/icons.py | 3 --
8 files changed, 69 insertions(+), 164 deletions(-)
delete mode 100644 nw/assets/graphics/export.svg
delete mode 100644 nw/assets/graphics/merge.svg
delete mode 100644 nw/assets/graphics/split.svg
diff --git a/nw/assets/graphics/export.svg b/nw/assets/graphics/export.svg
deleted file mode 100644
index 9594a980..00000000
--- a/nw/assets/graphics/export.svg
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
\ No newline at end of file
diff --git a/nw/assets/graphics/merge.svg b/nw/assets/graphics/merge.svg
deleted file mode 100644
index 1b4c6ae9..00000000
--- a/nw/assets/graphics/merge.svg
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
diff --git a/nw/assets/graphics/split.svg b/nw/assets/graphics/split.svg
deleted file mode 100644
index c427eea6..00000000
--- a/nw/assets/graphics/split.svg
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
diff --git a/nw/gui/additions/__init__.py b/nw/gui/additions/__init__.py
index 32af81f6..dbacd16e 100644
--- a/nw/gui/additions/__init__.py
+++ b/nw/gui/additions/__init__.py
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
from nw.gui.additions.pageddialog import PagedDialog
from nw.gui.additions.qconfiglayout import QConfigLayout
+from nw.gui.additions.qconfiglayout import QHelpLabel
from nw.gui.additions.qswitch import QSwitch
__all__ = [
"PagedDialog",
"QConfigLayout",
+ "QHelpLabel",
"QSwitch",
]
diff --git a/nw/gui/additions/qconfiglayout.py b/nw/gui/additions/qconfiglayout.py
index 51face15..032d0e6b 100644
--- a/nw/gui/additions/qconfiglayout.py
+++ b/nw/gui/additions/qconfiglayout.py
@@ -130,17 +130,9 @@ class QConfigLayout(QGridLayout):
qLabel.setIndent(8)
if helpText is not None:
- qHelp = QLabel(str(helpText))
+ qHelp = QHelpLabel(str(helpText), self._helpCol, self._fontScale)
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)
@@ -176,3 +168,25 @@ class QConfigLayout(QGridLayout):
return self._nextRow - 1
# END Class QConfigLayout
+
+class QHelpLabel(QLabel):
+
+ def __init__(self, theText, textCol, fontSize=0.9):
+ QLabel.__init__(self, 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)
+
+ return
+
+# END Class QHelpLabel
diff --git a/nw/gui/dialogs/docmerge.py b/nw/gui/dialogs/docmerge.py
index 1094fb78..47391a72 100644
--- a/nw/gui/dialogs/docmerge.py
+++ b/nw/gui/dialogs/docmerge.py
@@ -29,11 +29,14 @@ import logging
import nw
from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton,
- QListWidget, QAbstractItemView, QListWidgetItem
+ QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QLabel,
+ QListWidget, QAbstractItemView, QListWidgetItem, QDialogButtonBox
)
+
from nw.constants import nwAlert, nwItemType
+from nw.gui.additions import QHelpLabel
from nw.core import NWDoc
logger = logging.getLogger(__name__)
@@ -50,34 +53,31 @@ class GuiDocMerge(QDialog):
self.theProject = theProject
self.sourceItem = None
- self.outerBox = QHBoxLayout()
- self.innerBox = QVBoxLayout()
- self.setLayout(self.outerBox)
-
+ self.outerBox = QVBoxLayout()
self.setWindowTitle("Merge Documents")
- self.guiDeco = self.theParent.theTheme.loadDecoration("merge",(64,64))
- self.outerBox.setSpacing(16)
- self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop)
- self.outerBox.addLayout(self.innerBox)
-
- self.doMergeForm = QGridLayout()
- self.doMergeForm.setContentsMargins(0,0,0,0)
+ self.headLabel = QLabel("Documents to Merge")
+ self.helpLabel = QHelpLabel(
+ "Drag and drop items to change the order.", self.theParent.theTheme.helpText
+ )
self.listBox = QListWidget()
self.listBox.setDragDropMode(QAbstractItemView.InternalMove)
+ self.listBox.setMinimumWidth(400)
+ self.listBox.setMinimumHeight(180)
- self.mergeButton = QPushButton("Merge")
- self.mergeButton.clicked.connect(self._doMerge)
+ self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+ self.buttonBox.accepted.connect(self._doMerge)
+ self.buttonBox.rejected.connect(self._doClose)
- self.closeButton = QPushButton("Close")
- self.closeButton.clicked.connect(self._doClose)
-
- self.doMergeForm.addWidget(self.listBox, 0, 0, 1, 3)
- self.doMergeForm.addWidget(self.mergeButton, 1, 1)
- self.doMergeForm.addWidget(self.closeButton, 1, 2)
-
- self.innerBox.addLayout(self.doMergeForm)
+ self.outerBox.setSpacing(0)
+ self.outerBox.addWidget(self.headLabel)
+ self.outerBox.addWidget(self.helpLabel)
+ self.outerBox.addSpacing(8)
+ self.outerBox.addWidget(self.listBox)
+ self.outerBox.addSpacing(12)
+ self.outerBox.addWidget(self.buttonBox)
+ self.setLayout(self.outerBox)
self.rejected.connect(self._doClose)
self.show()
diff --git a/nw/gui/dialogs/docsplit.py b/nw/gui/dialogs/docsplit.py
index dc795c77..7e2e80cd 100644
--- a/nw/gui/dialogs/docsplit.py
+++ b/nw/gui/dialogs/docsplit.py
@@ -31,9 +31,10 @@ import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QComboBox,
- QListWidget, QAbstractItemView, QListWidgetItem
+ QListWidget, QAbstractItemView, QListWidgetItem, QDialogButtonBox, QLabel
)
from nw.constants import nwAlert, nwItemType, nwItemClass, nwItemLayout
+from nw.gui.additions import QHelpLabel
from nw.core import NWDoc
logger = logging.getLogger(__name__)
@@ -51,22 +52,18 @@ class GuiDocSplit(QDialog):
self.optState = self.theProject.optState
self.sourceItem = None
- self.outerBox = QHBoxLayout()
- self.innerBox = QVBoxLayout()
- self.setLayout(self.outerBox)
-
+ self.outerBox = QVBoxLayout()
self.setWindowTitle("Split Document")
- self.guiDeco = self.theParent.theTheme.loadDecoration("split",(64,64))
- self.outerBox.setSpacing(16)
- self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop)
- self.outerBox.addLayout(self.innerBox)
-
- self.doMergeForm = QGridLayout()
- self.doMergeForm.setContentsMargins(0,0,0,0)
+ self.headLabel = QLabel("Document Headers")
+ self.helpLabel = QHelpLabel(
+ "Select the maximum level to split into files at.", self.theParent.theTheme.helpText
+ )
self.listBox = QListWidget()
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
+ self.listBox.setMinimumWidth(400)
+ self.listBox.setMinimumHeight(180)
self.splitLevel = QComboBox(self)
self.splitLevel.addItem("Split on Header Level 1 (Title)", 1)
@@ -80,18 +77,19 @@ class GuiDocSplit(QDialog):
self.splitLevel.setCurrentIndex(spIndex)
self.splitLevel.currentIndexChanged.connect(self._populateList)
- self.splitButton = QPushButton("Split")
- self.splitButton.clicked.connect(self._doSplit)
+ self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+ self.buttonBox.accepted.connect(self._doSplit)
+ self.buttonBox.rejected.connect(self._doClose)
- self.closeButton = QPushButton("Close")
- self.closeButton.clicked.connect(self._doClose)
-
- self.doMergeForm.addWidget(self.listBox, 0, 0, 1, 3)
- self.doMergeForm.addWidget(self.splitLevel, 1, 0, 1, 3)
- self.doMergeForm.addWidget(self.splitButton, 2, 1)
- self.doMergeForm.addWidget(self.closeButton, 2, 2)
-
- self.innerBox.addLayout(self.doMergeForm)
+ self.outerBox.setSpacing(0)
+ self.outerBox.addWidget(self.headLabel)
+ self.outerBox.addWidget(self.helpLabel)
+ self.outerBox.addSpacing(8)
+ self.outerBox.addWidget(self.listBox)
+ self.outerBox.addWidget(self.splitLevel)
+ self.outerBox.addSpacing(12)
+ self.outerBox.addWidget(self.buttonBox)
+ self.setLayout(self.outerBox)
self.rejected.connect(self._doClose)
self.show()
diff --git a/nw/gui/icons.py b/nw/gui/icons.py
index 8457ea90..9340d900 100644
--- a/nw/gui/icons.py
+++ b/nw/gui/icons.py
@@ -99,10 +99,7 @@ class GuiIcons:
DECO_MAP = {
"nwicon" : ["icons", "novelWriter.svg"],
- "export" : ["graphics", "export.svg"],
- "merge" : ["graphics", "merge.svg"],
"settings" : ["graphics", "gear.svg"],
- "split" : ["graphics", "split.svg"],
}
def __init__(self, theParent):
From dec7e51a77ceb2bcf1d7319c89d7a9267e5204bf Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 17 May 2020 18:23:27 +0200
Subject: [PATCH 7/7] Cleaned up item editor, and removed some redundant
imports here and there
---
nw/assets/graphics/gear.svg | 48 -----------------------
nw/assets/graphics/license.txt | 8 ----
nw/gui/dialogs/docmerge.py | 5 +--
nw/gui/dialogs/docsplit.py | 4 +-
nw/gui/dialogs/itemeditor.py | 71 +++++++++++++++++++---------------
nw/gui/icons.py | 1 -
6 files changed, 44 insertions(+), 93 deletions(-)
delete mode 100644 nw/assets/graphics/gear.svg
delete mode 100644 nw/assets/graphics/license.txt
diff --git a/nw/assets/graphics/gear.svg b/nw/assets/graphics/gear.svg
deleted file mode 100644
index b5da5b7a..00000000
--- a/nw/assets/graphics/gear.svg
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
\ No newline at end of file
diff --git a/nw/assets/graphics/license.txt b/nw/assets/graphics/license.txt
deleted file mode 100644
index 00a23f87..00000000
--- a/nw/assets/graphics/license.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-FROM ICON SET: Typicons
-LICENSE: Creative Commons (Attribution-Share Alike 3.0 Unported)
-https://creativecommons.org/licenses/by-sa/3.0/
-
-Applies to:
- * graphics/export.svg
- * graphics/merge.svg
- * graphics/split.svg
diff --git a/nw/gui/dialogs/docmerge.py b/nw/gui/dialogs/docmerge.py
index 47391a72..39c7d0bf 100644
--- a/nw/gui/dialogs/docmerge.py
+++ b/nw/gui/dialogs/docmerge.py
@@ -29,10 +29,9 @@ import logging
import nw
from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QLabel,
- QListWidget, QAbstractItemView, QListWidgetItem, QDialogButtonBox
+ QDialog, QVBoxLayout, QLabel, QListWidget, QAbstractItemView,
+ QListWidgetItem, QDialogButtonBox
)
from nw.constants import nwAlert, nwItemType
diff --git a/nw/gui/dialogs/docsplit.py b/nw/gui/dialogs/docsplit.py
index 7e2e80cd..137138c3 100644
--- a/nw/gui/dialogs/docsplit.py
+++ b/nw/gui/dialogs/docsplit.py
@@ -30,8 +30,8 @@ import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QComboBox,
- QListWidget, QAbstractItemView, QListWidgetItem, QDialogButtonBox, QLabel
+ QDialog, QVBoxLayout, QComboBox, QListWidget, QAbstractItemView,
+ QListWidgetItem, QDialogButtonBox, QLabel
)
from nw.constants import nwAlert, nwItemType, nwItemClass, nwItemLayout
from nw.gui.additions import QHelpLabel
diff --git a/nw/gui/dialogs/itemeditor.py b/nw/gui/dialogs/itemeditor.py
index d2446579..51583195 100644
--- a/nw/gui/dialogs/itemeditor.py
+++ b/nw/gui/dialogs/itemeditor.py
@@ -30,11 +30,11 @@ import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QGroupBox, QGridLayout, QLineEdit,
- QComboBox, QLabel, QSpacerItem, QSizePolicy, QDialogButtonBox
+ QDialog, QVBoxLayout, QGridLayout, QLineEdit, QComboBox, QLabel,
+ QDialogButtonBox
)
-from nw.gui.additions import QSwitch
+from nw.gui.additions import QSwitch, QHelpLabel
from nw.constants import nwLabels, nwItemLayout, nwItemClass, nwItemType
logger = logging.getLogger(__name__)
@@ -49,31 +49,30 @@ class GuiItemEditor(QDialog):
self.mainConf = nw.CONFIG
self.theProject = theProject
self.theParent = theParent
- self.outerBox = QHBoxLayout()
- self.innerBox = QVBoxLayout()
- self.theItem = self.theProject.projTree[tHandle]
+ self.outerBox = QVBoxLayout()
+
+ self.theItem = self.theProject.projTree[tHandle]
if self.theItem is None:
self._doClose()
self.setWindowTitle("Item Settings")
- self.guiDeco = self.theParent.theTheme.loadDecoration("settings", (64,64))
- self.outerBox.setSpacing(16)
-
- self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop)
- self.outerBox.addLayout(self.innerBox)
self.setLayout(self.outerBox)
- self.mainGroup = QGroupBox("Item Settings")
- self.mainForm = QGridLayout()
+ # Labels
+ self.headLabel = QLabel("Edit Item Settings")
+ self.helpLabel = QHelpLabel(
+ "Item layout and status options depend on the root folder.",
+ self.theParent.theTheme.helpText
+ )
+ # Item Label
self.editName = QLineEdit()
self.editName.setMinimumWidth(220)
self.editName.setMaxLength(200)
+ # Item Status
self.editStatus = QComboBox()
- self.editLayout = QComboBox()
-
if self.theItem.itemClass == nwItemClass.NOVEL:
for sLabel, _, _ in self.theProject.statusItems:
self.editStatus.addItem(
@@ -85,6 +84,8 @@ class GuiItemEditor(QDialog):
self.theParent.importIcons[sLabel], sLabel, sLabel
)
+ # Item Layout
+ self.editLayout = QComboBox()
self.validLayouts = []
if self.theItem.itemType == nwItemType.FILE:
if self.theItem.itemClass == nwItemClass.NOVEL:
@@ -105,6 +106,7 @@ class GuiItemEditor(QDialog):
if itemLayout in self.validLayouts:
self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout],itemLayout)
+ # Export Switch
self.textExport = QLabel("Include when building project")
self.editExport = QSwitch()
if self.theItem.itemType == nwItemType.FILE:
@@ -114,18 +116,6 @@ class GuiItemEditor(QDialog):
self.editExport.setEnabled(False)
self.editExport.setChecked(False)
- self.mainForm.addWidget(QLabel("Label"), 0, 0)
- self.mainForm.addWidget(self.editName, 0, 1, 1, 2)
- self.mainForm.addWidget(QLabel("Status"), 1, 0)
- self.mainForm.addWidget(self.editStatus, 1, 1, 1, 2)
- self.mainForm.addWidget(QLabel("Layout"), 2, 0)
- self.mainForm.addWidget(self.editLayout, 2, 1, 1, 2)
- self.mainForm.addWidget(self.textExport, 4, 0, 1, 2)
- self.mainForm.addWidget(self.editExport, 4, 2)
-
- self.spacerItem = QSpacerItem(12, 12, QSizePolicy.Fixed, QSizePolicy.Fixed)
- self.mainForm.addItem(self.spacerItem, 3, 0)
-
self.editName.setText(self.theItem.itemName)
statusIdx = self.editStatus.findData(self.theItem.itemStatus)
if statusIdx != -1:
@@ -134,14 +124,34 @@ class GuiItemEditor(QDialog):
if layoutIdx != -1:
self.editLayout.setCurrentIndex(layoutIdx)
+ # Buttons
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
- self.mainGroup.setLayout(self.mainForm)
- self.innerBox.addWidget(self.mainGroup)
- self.innerBox.addWidget(self.buttonBox)
+ # Assemble
+ self.mainForm = QGridLayout()
+ self.mainForm.setVerticalSpacing(4)
+ self.mainForm.addWidget(QLabel("Label"), 0, 0, 1, 1)
+ self.mainForm.addWidget(self.editName, 0, 1, 1, 2)
+ self.mainForm.addWidget(QLabel("Status"), 1, 0, 1, 1)
+ self.mainForm.addWidget(self.editStatus, 1, 1, 1, 2)
+ self.mainForm.addWidget(QLabel("Layout"), 2, 0, 1, 1)
+ self.mainForm.addWidget(self.editLayout, 2, 1, 1, 2)
+ self.mainForm.addWidget(self.textExport, 3, 0, 1, 2)
+ self.mainForm.addWidget(self.editExport, 3, 2, 1, 1)
+ self.outerBox.setSpacing(0)
+ self.outerBox.addWidget(self.headLabel)
+ self.outerBox.addWidget(self.helpLabel)
+ self.outerBox.addSpacing(8)
+ self.outerBox.addLayout(self.mainForm)
+ self.outerBox.addSpacing(12)
+ self.outerBox.addStretch(1)
+ self.outerBox.addWidget(self.buttonBox)
+ self.setLayout(self.outerBox)
+
+ self.rejected.connect(self._doClose)
self.show()
self.editName.selectAll()
@@ -175,7 +185,6 @@ class GuiItemEditor(QDialog):
def _doClose(self):
logger.verbose("ItemEditor close button clicked")
- self.reject()
self.close()
return
diff --git a/nw/gui/icons.py b/nw/gui/icons.py
index 9340d900..bc0bd493 100644
--- a/nw/gui/icons.py
+++ b/nw/gui/icons.py
@@ -99,7 +99,6 @@ class GuiIcons:
DECO_MAP = {
"nwicon" : ["icons", "novelWriter.svg"],
- "settings" : ["graphics", "gear.svg"],
}
def __init__(self, theParent):