Add shape selector to project settings
This commit is contained in:
@@ -25,7 +25,7 @@ from __future__ import annotations
|
||||
|
||||
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:
|
||||
@@ -268,6 +268,15 @@ class nwLabels:
|
||||
nwBuildFmt.J_HTML: ".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 = {
|
||||
"*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"),
|
||||
"*.md": QT_TRANSLATE_NOOP("Constant", "Markdown files"),
|
||||
|
||||
@@ -30,12 +30,13 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout,
|
||||
QLineEdit, QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
QLineEdit, QPushButton, QSizePolicy, QStackedWidget, QTreeWidget,
|
||||
QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import simplified
|
||||
from novelwriter.constants import nwLabels
|
||||
from novelwriter.core.status import NWStatus, StatusEntry
|
||||
from novelwriter.enum import nwStatusShape
|
||||
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
|
||||
@@ -182,14 +183,17 @@ class GuiProjectSettings(QDialog):
|
||||
rebuildTrees = False
|
||||
|
||||
if self.statusPage.changed:
|
||||
logger.debug("Updating status labels")
|
||||
project.data.itemStatus.update(self.statusPage.getNewList())
|
||||
rebuildTrees = True
|
||||
|
||||
if self.importPage.changed:
|
||||
logger.debug("Updating importance labels")
|
||||
project.data.itemImport.update(self.importPage.getNewList())
|
||||
rebuildTrees = True
|
||||
|
||||
if self.replacePage.changed:
|
||||
logger.debug("Updating auto-replace settings")
|
||||
project.data.setAutoReplace(self.replacePage.getNewList())
|
||||
|
||||
self.newProjectSettingsReady.emit(rebuildTrees)
|
||||
@@ -324,7 +328,7 @@ class _StatusPage(NFixedPage):
|
||||
)
|
||||
|
||||
self._changed = False
|
||||
self._selColour = QColor(100, 100, 100)
|
||||
self._color = QColor(100, 100, 100)
|
||||
|
||||
self._iPx = SHARED.theme.baseIconHeight
|
||||
iSz = SHARED.theme.baseIconSize
|
||||
@@ -334,6 +338,7 @@ class _StatusPage(NFixedPage):
|
||||
self.trCountNone = self.tr("Not in use")
|
||||
self.trCountOne = self.tr("Used once")
|
||||
self.trCountMore = self.tr("Used by {0} items")
|
||||
self.trSelColor = self.tr("Select Colour")
|
||||
|
||||
# Title
|
||||
self.pageTitle = NColourLabel(
|
||||
@@ -370,15 +375,22 @@ class _StatusPage(NFixedPage):
|
||||
self.editName.setPlaceholderText(self.tr("Select item to edit"))
|
||||
self.editName.setEnabled(False)
|
||||
|
||||
self.colPixmap = QPixmap(self._iPx, self._iPx)
|
||||
self.colPixmap.fill(QColor(100, 100, 100))
|
||||
self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"), self)
|
||||
self.colButton.setIconSize(bSz)
|
||||
self.colButton = QPushButton("", self)
|
||||
self.colButton.setEnabled(False)
|
||||
self.colButton.setIconSize(bSz)
|
||||
self.colButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
|
||||
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.setEnabled(False)
|
||||
self.saveButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
|
||||
self.saveButton.clicked.connect(self._saveItem)
|
||||
|
||||
# Assemble
|
||||
@@ -390,13 +402,14 @@ class _StatusPage(NFixedPage):
|
||||
self.listControls.addStretch(1)
|
||||
|
||||
self.editBox = QHBoxLayout()
|
||||
self.editBox.addWidget(self.editName)
|
||||
self.editBox.addWidget(self.colButton)
|
||||
self.editBox.addWidget(self.saveButton)
|
||||
self.editBox.addWidget(self.editName, 1)
|
||||
self.editBox.addWidget(self.colButton, 0)
|
||||
self.editBox.addWidget(self.shapeList, 0)
|
||||
self.editBox.addWidget(self.saveButton, 0)
|
||||
|
||||
self.mainBox = QVBoxLayout()
|
||||
self.mainBox.addWidget(self.listBox)
|
||||
self.mainBox.addLayout(self.editBox)
|
||||
self.mainBox.addWidget(self.listBox, 1)
|
||||
self.mainBox.addLayout(self.editBox, 0)
|
||||
|
||||
self.innerBox = QHBoxLayout()
|
||||
self.innerBox.addLayout(self.mainBox)
|
||||
@@ -442,16 +455,9 @@ class _StatusPage(NFixedPage):
|
||||
@pyqtSlot()
|
||||
def _selectColour(self) -> None:
|
||||
"""Open a dialog to select the status icon colour."""
|
||||
if self._selColour is not None:
|
||||
newCol = QColorDialog.getColor(
|
||||
self._selColour, self, self.tr("Select Colour")
|
||||
)
|
||||
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())
|
||||
if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
|
||||
self._color = color
|
||||
self._setColButton(color)
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -484,16 +490,20 @@ class _StatusPage(NFixedPage):
|
||||
entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY)
|
||||
|
||||
name = simplified(self.editName.text())
|
||||
shape = nwStatusShape.SQUARE
|
||||
icon = NWStatus.createIcon(self._iPx, self._selColour, shape)
|
||||
selected = self.shapeList.currentData()
|
||||
shape = selected if isinstance(selected, nwStatusShape) else nwStatusShape.SQUARE
|
||||
icon = NWStatus.createIcon(self._iPx, self._color, shape)
|
||||
|
||||
entry.name = name
|
||||
entry.color = self._color
|
||||
entry.shape = shape
|
||||
entry.color = self._selColour
|
||||
entry.icon = icon
|
||||
|
||||
item.setText(self.C_LABEL, name)
|
||||
item.setIcon(self.C_LABEL, icon)
|
||||
|
||||
self._changed = True
|
||||
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -503,21 +513,28 @@ class _StatusPage(NFixedPage):
|
||||
"""
|
||||
if item := self._getSelectedItem():
|
||||
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.colButton.setIcon(entry.icon)
|
||||
self.editName.selectAll()
|
||||
self.editName.setFocus()
|
||||
self.shapeList.setCurrentData(entry.shape, nwStatusShape.SQUARE)
|
||||
|
||||
self.editName.setEnabled(True)
|
||||
self.colButton.setEnabled(True)
|
||||
self.shapeList.setEnabled(True)
|
||||
self.saveButton.setEnabled(True)
|
||||
|
||||
else:
|
||||
self._selColour = QColor(100, 100, 100)
|
||||
icon = NWStatus.createIcon(self._iPx, self._selColour, nwStatusShape.SQUARE)
|
||||
self._color = QColor(100, 100, 100)
|
||||
self._setColButton(self._color)
|
||||
self.editName.setText("")
|
||||
self.colButton.setIcon(icon)
|
||||
self.shapeList.setCurrentIndex(0)
|
||||
|
||||
self.editName.setEnabled(False)
|
||||
self.colButton.setEnabled(False)
|
||||
self.shapeList.setEnabled(False)
|
||||
self.saveButton.setEnabled(False)
|
||||
return
|
||||
|
||||
@@ -564,6 +581,14 @@ class _StatusPage(NFixedPage):
|
||||
else:
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from PyQt5.QtCore import QSize, Qt
|
||||
from PyQt5.QtGui import QWheelEvent
|
||||
from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget
|
||||
@@ -46,7 +48,7 @@ class NComboBox(QComboBox):
|
||||
event.ignore()
|
||||
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."""
|
||||
idx = self.findData(data)
|
||||
self.setCurrentIndex(self.findData(default) if idx < 0 else idx)
|
||||
|
||||
+13
-13
@@ -1,6 +1,6 @@
|
||||
<?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">
|
||||
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1699" autoCount="264" editTime="83349">
|
||||
<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="1830" autoCount="265" editTime="85357">
|
||||
<name>Sample Project</name>
|
||||
<author>Jane Smith</author>
|
||||
</project>
|
||||
@@ -20,19 +20,19 @@
|
||||
<entry key="C">D</entry>
|
||||
</autoReplace>
|
||||
<status>
|
||||
<entry key="sf12341" count="8" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="sf24ce6" count="2" red="200" green="50" blue="0">Notes</entry>
|
||||
<entry key="sc24b8f" count="3" red="182" green="60" blue="0">Started</entry>
|
||||
<entry key="s90e6c9" count="7" red="193" green="129" blue="0">1st Draft</entry>
|
||||
<entry key="sd51c5b" count="0" red="193" green="129" blue="0">2nd Draft</entry>
|
||||
<entry key="s8ae72a" count="0" red="193" green="129" blue="0">3rd Draft</entry>
|
||||
<entry key="s78ea90" count="1" red="58" green="180" blue="58">Finished</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" shape="SQUARE">Notes</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" shape="SQUARE">1st 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" shape="SQUARE">3rd Draft</entry>
|
||||
<entry key="s78ea90" count="1" red="58" green="180" blue="58" shape="STAR">Finished</entry>
|
||||
</status>
|
||||
<importance>
|
||||
<entry key="ia857f0" count="5" red="100" green="100" blue="100">None</entry>
|
||||
<entry key="icfb3a5" count="2" red="0" green="122" blue="188">Minor</entry>
|
||||
<entry key="i2d7a54" count="2" red="21" green="0" blue="180">Major</entry>
|
||||
<entry key="i56be10" count="1" red="117" green="0" blue="175">Main</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" shape="CIRCLE">Minor</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" shape="CIRCLE">Main</entry>
|
||||
</importance>
|
||||
</settings>
|
||||
<content items="31" novelWords="998" notesWords="416">
|
||||
|
||||
Reference in New Issue
Block a user