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 @@ - -image/svg+xml \ 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 @@ - - - - - - image/svg+xml - - - - - - - - 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 @@ - - - - - - image/svg+xml - - - - - - - - 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 @@ - -image/svg+xml - - \ 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):