Add shape selector to project settings

This commit is contained in:
Veronica Berglyd Olsen
2024-04-10 23:24:00 +02:00
parent d1dbb0b378
commit 778b65b48c
4 changed files with 81 additions and 45 deletions
+10 -1
View File
@@ -25,7 +25,7 @@ from __future__ import annotations
from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP
from novelwriter.enum import nwBuildFmt, nwItemClass, nwItemLayout, nwOutline from novelwriter.enum import nwBuildFmt, nwItemClass, nwItemLayout, nwOutline, nwStatusShape
def trConst(text: str) -> str: def trConst(text: str) -> str:
@@ -268,6 +268,15 @@ class nwLabels:
nwBuildFmt.J_HTML: ".json", nwBuildFmt.J_HTML: ".json",
nwBuildFmt.J_NWD: ".json", nwBuildFmt.J_NWD: ".json",
} }
STATUS_SHAPES = {
nwStatusShape.SQUARE: QT_TRANSLATE_NOOP("Constant", "Square"),
nwStatusShape.CIRCLE: QT_TRANSLATE_NOOP("Constant", "Circle"),
nwStatusShape.TRIANGLE: QT_TRANSLATE_NOOP("Constant", "Triangle"),
nwStatusShape.DIAMOND: QT_TRANSLATE_NOOP("Constant", "Diamond"),
nwStatusShape.PENTAGON: QT_TRANSLATE_NOOP("Constant", "Pentagon"),
nwStatusShape.STAR: QT_TRANSLATE_NOOP("Constant", "Star"),
nwStatusShape.PACMAN: QT_TRANSLATE_NOOP("Constant", "Pacman"),
}
FILE_FILTERS = { FILE_FILTERS = {
"*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"), "*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"),
"*.md": QT_TRANSLATE_NOOP("Constant", "Markdown files"), "*.md": QT_TRANSLATE_NOOP("Constant", "Markdown files"),
+55 -30
View File
@@ -30,12 +30,13 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout, QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout,
QLineEdit, QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem, QLineEdit, QPushButton, QSizePolicy, QStackedWidget, QTreeWidget,
QVBoxLayout, QWidget QTreeWidgetItem, QVBoxLayout, QWidget
) )
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import simplified from novelwriter.common import simplified
from novelwriter.constants import nwLabels
from novelwriter.core.status import NWStatus, StatusEntry from novelwriter.core.status import NWStatus, StatusEntry
from novelwriter.enum import nwStatusShape from novelwriter.enum import nwStatusShape
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
@@ -182,14 +183,17 @@ class GuiProjectSettings(QDialog):
rebuildTrees = False rebuildTrees = False
if self.statusPage.changed: if self.statusPage.changed:
logger.debug("Updating status labels")
project.data.itemStatus.update(self.statusPage.getNewList()) project.data.itemStatus.update(self.statusPage.getNewList())
rebuildTrees = True rebuildTrees = True
if self.importPage.changed: if self.importPage.changed:
logger.debug("Updating importance labels")
project.data.itemImport.update(self.importPage.getNewList()) project.data.itemImport.update(self.importPage.getNewList())
rebuildTrees = True rebuildTrees = True
if self.replacePage.changed: if self.replacePage.changed:
logger.debug("Updating auto-replace settings")
project.data.setAutoReplace(self.replacePage.getNewList()) project.data.setAutoReplace(self.replacePage.getNewList())
self.newProjectSettingsReady.emit(rebuildTrees) self.newProjectSettingsReady.emit(rebuildTrees)
@@ -324,7 +328,7 @@ class _StatusPage(NFixedPage):
) )
self._changed = False self._changed = False
self._selColour = QColor(100, 100, 100) self._color = QColor(100, 100, 100)
self._iPx = SHARED.theme.baseIconHeight self._iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize iSz = SHARED.theme.baseIconSize
@@ -334,6 +338,7 @@ class _StatusPage(NFixedPage):
self.trCountNone = self.tr("Not in use") self.trCountNone = self.tr("Not in use")
self.trCountOne = self.tr("Used once") self.trCountOne = self.tr("Used once")
self.trCountMore = self.tr("Used by {0} items") self.trCountMore = self.tr("Used by {0} items")
self.trSelColor = self.tr("Select Colour")
# Title # Title
self.pageTitle = NColourLabel( self.pageTitle = NColourLabel(
@@ -370,15 +375,22 @@ class _StatusPage(NFixedPage):
self.editName.setPlaceholderText(self.tr("Select item to edit")) self.editName.setPlaceholderText(self.tr("Select item to edit"))
self.editName.setEnabled(False) self.editName.setEnabled(False)
self.colPixmap = QPixmap(self._iPx, self._iPx) self.colButton = QPushButton("", self)
self.colPixmap.fill(QColor(100, 100, 100))
self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"), self)
self.colButton.setIconSize(bSz)
self.colButton.setEnabled(False) self.colButton.setEnabled(False)
self.colButton.setIconSize(bSz)
self.colButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.colButton.clicked.connect(self._selectColour) self.colButton.clicked.connect(self._selectColour)
self._setColButton(self._color)
self.shapeList = NComboBox(self)
self.shapeList.setEnabled(False)
self.shapeList.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
for shape, label in nwLabels.STATUS_SHAPES.items():
self.shapeList.addItem(label, shape)
self.saveButton = QPushButton(self.tr("Save"), self) self.saveButton = QPushButton(self.tr("Save"), self)
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
self.saveButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.saveButton.clicked.connect(self._saveItem) self.saveButton.clicked.connect(self._saveItem)
# Assemble # Assemble
@@ -390,13 +402,14 @@ class _StatusPage(NFixedPage):
self.listControls.addStretch(1) self.listControls.addStretch(1)
self.editBox = QHBoxLayout() self.editBox = QHBoxLayout()
self.editBox.addWidget(self.editName) self.editBox.addWidget(self.editName, 1)
self.editBox.addWidget(self.colButton) self.editBox.addWidget(self.colButton, 0)
self.editBox.addWidget(self.saveButton) self.editBox.addWidget(self.shapeList, 0)
self.editBox.addWidget(self.saveButton, 0)
self.mainBox = QVBoxLayout() self.mainBox = QVBoxLayout()
self.mainBox.addWidget(self.listBox) self.mainBox.addWidget(self.listBox, 1)
self.mainBox.addLayout(self.editBox) self.mainBox.addLayout(self.editBox, 0)
self.innerBox = QHBoxLayout() self.innerBox = QHBoxLayout()
self.innerBox.addLayout(self.mainBox) self.innerBox.addLayout(self.mainBox)
@@ -442,16 +455,9 @@ class _StatusPage(NFixedPage):
@pyqtSlot() @pyqtSlot()
def _selectColour(self) -> None: def _selectColour(self) -> None:
"""Open a dialog to select the status icon colour.""" """Open a dialog to select the status icon colour."""
if self._selColour is not None: if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
newCol = QColorDialog.getColor( self._color = color
self._selColour, self, self.tr("Select Colour") self._setColButton(color)
)
if newCol.isValid():
self._selColour = newCol
pixmap = QPixmap(self._iPx, self._iPx)
pixmap.fill(newCol)
self.colButton.setIcon(QIcon(pixmap))
self.colButton.setIconSize(pixmap.rect().size())
return return
@pyqtSlot() @pyqtSlot()
@@ -484,16 +490,20 @@ class _StatusPage(NFixedPage):
entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY) entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY)
name = simplified(self.editName.text()) name = simplified(self.editName.text())
shape = nwStatusShape.SQUARE selected = self.shapeList.currentData()
icon = NWStatus.createIcon(self._iPx, self._selColour, shape) shape = selected if isinstance(selected, nwStatusShape) else nwStatusShape.SQUARE
icon = NWStatus.createIcon(self._iPx, self._color, shape)
entry.name = name entry.name = name
entry.color = self._color
entry.shape = shape entry.shape = shape
entry.color = self._selColour
entry.icon = icon entry.icon = icon
item.setText(self.C_LABEL, name) item.setText(self.C_LABEL, name)
item.setIcon(self.C_LABEL, icon) item.setIcon(self.C_LABEL, icon)
self._changed = True self._changed = True
return return
@pyqtSlot() @pyqtSlot()
@@ -503,21 +513,28 @@ class _StatusPage(NFixedPage):
""" """
if item := self._getSelectedItem(): if item := self._getSelectedItem():
entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY) entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY)
self._selColour = entry.color self._color = entry.color
self._setColButton(entry.color)
self.editName.setText(entry.name) self.editName.setText(entry.name)
self.colButton.setIcon(entry.icon)
self.editName.selectAll() self.editName.selectAll()
self.editName.setFocus() self.editName.setFocus()
self.shapeList.setCurrentData(entry.shape, nwStatusShape.SQUARE)
self.editName.setEnabled(True) self.editName.setEnabled(True)
self.colButton.setEnabled(True) self.colButton.setEnabled(True)
self.shapeList.setEnabled(True)
self.saveButton.setEnabled(True) self.saveButton.setEnabled(True)
else: else:
self._selColour = QColor(100, 100, 100) self._color = QColor(100, 100, 100)
icon = NWStatus.createIcon(self._iPx, self._selColour, nwStatusShape.SQUARE) self._setColButton(self._color)
self.editName.setText("") self.editName.setText("")
self.colButton.setIcon(icon) self.shapeList.setCurrentIndex(0)
self.editName.setEnabled(False) self.editName.setEnabled(False)
self.colButton.setEnabled(False) self.colButton.setEnabled(False)
self.shapeList.setEnabled(False)
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
return return
@@ -564,6 +581,14 @@ class _StatusPage(NFixedPage):
else: else:
return self.trCountMore.format(count) return self.trCountMore.format(count)
def _setColButton(self, color: QColor) -> None:
"""Set the colour of the colour button."""
pixmap = QPixmap(self._iPx, self._iPx)
pixmap.fill(color)
self.colButton.setIcon(QIcon(pixmap))
self.colButton.setIconSize(pixmap.rect().size())
return
# END Class _StatusPage # END Class _StatusPage
+3 -1
View File
@@ -25,6 +25,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
from __future__ import annotations from __future__ import annotations
from enum import Enum
from PyQt5.QtCore import QSize, Qt from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import QWheelEvent from PyQt5.QtGui import QWheelEvent
from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget
@@ -46,7 +48,7 @@ class NComboBox(QComboBox):
event.ignore() event.ignore()
return return
def setCurrentData(self, data: str, default: str) -> None: def setCurrentData(self, data: str | Enum, default: str | Enum) -> None:
"""Set the current index from data, with a fallback.""" """Set the current index from data, with a fallback."""
idx = self.findData(data) idx = self.findData(data)
self.setCurrentIndex(self.findData(default) if idx < 0 else idx) self.setCurrentIndex(self.findData(default) if idx < 0 else idx)
+13 -13
View File
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.4rc1" hexVersion="0x020400c1" fileVersion="1.5" fileRevision="3" timeStamp="2024-04-06 15:52:29"> <novelWriterXML appVersion="2.4rc1" hexVersion="0x020400c1" fileVersion="1.5" fileRevision="4" timeStamp="2024-04-10 23:22:12">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1699" autoCount="264" editTime="83349"> <project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1830" autoCount="265" editTime="85357">
<name>Sample Project</name> <name>Sample Project</name>
<author>Jane Smith</author> <author>Jane Smith</author>
</project> </project>
@@ -20,19 +20,19 @@
<entry key="C">D</entry> <entry key="C">D</entry>
</autoReplace> </autoReplace>
<status> <status>
<entry key="sf12341" count="8" red="100" green="100" blue="100">New</entry> <entry key="sf12341" count="8" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="sf24ce6" count="2" red="200" green="50" blue="0">Notes</entry> <entry key="sf24ce6" count="2" red="200" green="50" blue="0" shape="SQUARE">Notes</entry>
<entry key="sc24b8f" count="3" red="182" green="60" blue="0">Started</entry> <entry key="sc24b8f" count="3" red="182" green="60" blue="0" shape="SQUARE">Started</entry>
<entry key="s90e6c9" count="7" red="193" green="129" blue="0">1st Draft</entry> <entry key="s90e6c9" count="7" red="193" green="129" blue="0" shape="SQUARE">1st Draft</entry>
<entry key="sd51c5b" count="0" red="193" green="129" blue="0">2nd Draft</entry> <entry key="sd51c5b" count="0" red="193" green="129" blue="0" shape="SQUARE">2nd Draft</entry>
<entry key="s8ae72a" count="0" red="193" green="129" blue="0">3rd Draft</entry> <entry key="s8ae72a" count="0" red="193" green="129" blue="0" shape="SQUARE">3rd Draft</entry>
<entry key="s78ea90" count="1" red="58" green="180" blue="58">Finished</entry> <entry key="s78ea90" count="1" red="58" green="180" blue="58" shape="STAR">Finished</entry>
</status> </status>
<importance> <importance>
<entry key="ia857f0" count="5" red="100" green="100" blue="100">None</entry> <entry key="ia857f0" count="5" red="100" green="100" blue="100" shape="CIRCLE">None</entry>
<entry key="icfb3a5" count="2" red="0" green="122" blue="188">Minor</entry> <entry key="icfb3a5" count="2" red="0" green="122" blue="188" shape="CIRCLE">Minor</entry>
<entry key="i2d7a54" count="2" red="21" green="0" blue="180">Major</entry> <entry key="i2d7a54" count="2" red="21" green="0" blue="180" shape="CIRCLE">Major</entry>
<entry key="i56be10" count="1" red="117" green="0" blue="175">Main</entry> <entry key="i56be10" count="1" red="117" green="0" blue="175" shape="CIRCLE">Main</entry>
</importance> </importance>
</settings> </settings>
<content items="31" novelWords="998" notesWords="416"> <content items="31" novelWords="998" notesWords="416">