Redesign status item controls, and clean up auto-replace methods

This commit is contained in:
Veronica Berglyd Olsen
2024-04-11 21:35:25 +02:00
parent f67d2c5a4c
commit 21a5dbbb52
2 changed files with 119 additions and 97 deletions
+27 -21
View File
@@ -268,27 +268,33 @@ class nwLabels:
nwBuildFmt.J_HTML: ".json", nwBuildFmt.J_HTML: ".json",
nwBuildFmt.J_NWD: ".json", nwBuildFmt.J_NWD: ".json",
} }
STATUS_SHAPES = { SHAPES_PLAIN = {
nwStatusShape.SQUARE: QT_TRANSLATE_NOOP("Constant", "Square"), nwStatusShape.SQUARE: QT_TRANSLATE_NOOP("Constant", "Square"),
nwStatusShape.TRIANGLE: QT_TRANSLATE_NOOP("Constant", "Triangle"), nwStatusShape.TRIANGLE: QT_TRANSLATE_NOOP("Constant", "Triangle"),
nwStatusShape.NABLA: QT_TRANSLATE_NOOP("Constant", "Nabla"), nwStatusShape.NABLA: QT_TRANSLATE_NOOP("Constant", "Nabla"),
nwStatusShape.DIAMOND: QT_TRANSLATE_NOOP("Constant", "Diamond"), nwStatusShape.DIAMOND: QT_TRANSLATE_NOOP("Constant", "Diamond"),
nwStatusShape.PENTAGON: QT_TRANSLATE_NOOP("Constant", "Pentagon"), nwStatusShape.PENTAGON: QT_TRANSLATE_NOOP("Constant", "Pentagon"),
nwStatusShape.HEXAGON: QT_TRANSLATE_NOOP("Constant", "Hexagon"), nwStatusShape.HEXAGON: QT_TRANSLATE_NOOP("Constant", "Hexagon"),
nwStatusShape.STAR: QT_TRANSLATE_NOOP("Constant", "Star"), nwStatusShape.STAR: QT_TRANSLATE_NOOP("Constant", "Star"),
nwStatusShape.PACMAN: QT_TRANSLATE_NOOP("Constant", "Pacman"), nwStatusShape.PACMAN: QT_TRANSLATE_NOOP("Constant", "Pacman"),
nwStatusShape.CIRCLE_Q: QT_TRANSLATE_NOOP("Constant", "Circle, 1/4"), }
nwStatusShape.CIRCLE_H: QT_TRANSLATE_NOOP("Constant", "Circle, Half"), SHAPES_CIRCLE = {
nwStatusShape.CIRCLE_T: QT_TRANSLATE_NOOP("Constant", "Circle, 3/4"), nwStatusShape.CIRCLE_Q: QT_TRANSLATE_NOOP("Constant", "1/4 Circle"),
nwStatusShape.CIRCLE: QT_TRANSLATE_NOOP("Constant", "Circle, Full"), nwStatusShape.CIRCLE_H: QT_TRANSLATE_NOOP("Constant", "Half Circle"),
nwStatusShape.BARS_1: QT_TRANSLATE_NOOP("Constant", "1 Bar"), nwStatusShape.CIRCLE_T: QT_TRANSLATE_NOOP("Constant", "3/4 Circle"),
nwStatusShape.BARS_2: QT_TRANSLATE_NOOP("Constant", "2 Bars"), nwStatusShape.CIRCLE: QT_TRANSLATE_NOOP("Constant", "Full Circle"),
nwStatusShape.BARS_3: QT_TRANSLATE_NOOP("Constant", "3 Bars"), }
nwStatusShape.BARS_4: QT_TRANSLATE_NOOP("Constant", "4 Bars"), SHAPES_BARS = {
nwStatusShape.BLOCK_1: QT_TRANSLATE_NOOP("Constant", "1 Block"), nwStatusShape.BARS_1: QT_TRANSLATE_NOOP("Constant", "1 Bar"),
nwStatusShape.BLOCK_2: QT_TRANSLATE_NOOP("Constant", "2 Blocks"), nwStatusShape.BARS_2: QT_TRANSLATE_NOOP("Constant", "2 Bars"),
nwStatusShape.BLOCK_3: QT_TRANSLATE_NOOP("Constant", "3 Blocks"), nwStatusShape.BARS_3: QT_TRANSLATE_NOOP("Constant", "3 Bars"),
nwStatusShape.BLOCK_4: QT_TRANSLATE_NOOP("Constant", "4 Blocks"), nwStatusShape.BARS_4: QT_TRANSLATE_NOOP("Constant", "4 Bars"),
}
SHAPES_BLOCKS = {
nwStatusShape.BLOCK_1: QT_TRANSLATE_NOOP("Constant", "1 Block"),
nwStatusShape.BLOCK_2: QT_TRANSLATE_NOOP("Constant", "2 Blocks"),
nwStatusShape.BLOCK_3: QT_TRANSLATE_NOOP("Constant", "3 Blocks"),
nwStatusShape.BLOCK_4: QT_TRANSLATE_NOOP("Constant", "4 Blocks"),
} }
FILE_FILTERS = { FILE_FILTERS = {
"*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"), "*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"),
+92 -76
View File
@@ -27,10 +27,10 @@ from __future__ import annotations
import logging import logging
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap from PyQt5.QtGui import QCloseEvent, QColor
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout, QApplication, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout,
QLineEdit, QPushButton, QSizePolicy, QStackedWidget, QTreeWidget, QLineEdit, QMenu, QSizePolicy, QStackedWidget, QToolButton, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget QTreeWidgetItem, QVBoxLayout, QWidget
) )
@@ -329,10 +329,12 @@ class _StatusPage(NFixedPage):
self._changed = False self._changed = False
self._color = QColor(100, 100, 100) self._color = QColor(100, 100, 100)
self._shape = nwStatusShape.SQUARE
self._icons = {}
self._iPx = SHARED.theme.baseIconHeight self._iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize iSz = SHARED.theme.baseIconSize
bSz = SHARED.theme.buttonIconSize bPd = CONFIG.pxInt(4)
iColor = self.palette().text().color() iColor = self.palette().text().color()
@@ -351,9 +353,9 @@ class _StatusPage(NFixedPage):
# List Box # List Box
self.listBox = QTreeWidget(self) self.listBox = QTreeWidget(self)
self.listBox.setHeaderLabels([self.tr("Label"), self.tr("Usage")]) self.listBox.setHeaderLabels([self.tr("Label"), self.tr("Usage")])
self.listBox.itemSelectionChanged.connect(self._selectedItem)
self.listBox.setColumnWidth(self.C_LABEL, wCol0) self.listBox.setColumnWidth(self.C_LABEL, wCol0)
self.listBox.setIndentation(0) self.listBox.setIndentation(0)
self.listBox.itemSelectionChanged.connect(self._selectedItem)
for key, entry in status.iterItems(): for key, entry in status.iterItems():
self._addItem(key, StatusEntry.duplicate(entry)) self._addItem(key, StatusEntry.duplicate(entry))
@@ -377,24 +379,42 @@ 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.colButton = QPushButton("", self) buttonStyle = (
self.colButton.setEnabled(False) f"QToolButton {{padding: 0 {bPd}px;}} "
self.colButton.setIconSize(bSz) "QToolButton::menu-indicator {image: none;}"
self.colButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) )
self.colButton.clicked.connect(self._selectColour)
self._setColButton(self._color)
self.shapeList = NComboBox(self) self.colorButton = NIconToolButton(self, iSz)
self.shapeList.setEnabled(False) self.colorButton.setToolTip(self.tr("Colour"))
self.shapeList.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self.colorButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.shapeList.setMaxVisibleItems(5) self.colorButton.setStyleSheet(buttonStyle)
for shape, label in nwLabels.STATUS_SHAPES.items(): self.colorButton.setEnabled(False)
icon = NWStatus.createIcon(self._iPx, iColor, shape) self.colorButton.clicked.connect(self._selectColour)
self.shapeList.addItem(icon, label, shape)
self.applyButton = QPushButton(self.tr("Apply"), self) def buildMenu(menu: QMenu, items: dict[nwStatusShape, str]) -> None:
self.applyButton.setEnabled(False) for shape, label in items.items():
icon = NWStatus.createIcon(self._iPx, iColor, shape)
action = menu.addAction(icon, label)
action.triggered.connect(lambda _, shape=shape: self._selectShape(shape))
self._icons[shape] = icon
self.shapeMenu = QMenu(self)
buildMenu(self.shapeMenu, nwLabels.SHAPES_PLAIN)
buildMenu(self.shapeMenu.addMenu(self.tr("Circles ...")), nwLabels.SHAPES_CIRCLE)
buildMenu(self.shapeMenu.addMenu(self.tr("Bars ...")), nwLabels.SHAPES_BARS)
buildMenu(self.shapeMenu.addMenu(self.tr("Blocks ...")), nwLabels.SHAPES_BLOCKS)
self.shapeButton = NIconToolButton(self, iSz)
self.shapeButton.setMenu(self.shapeMenu)
self.shapeButton.setToolTip(self.tr("Shape"))
self.shapeButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.shapeButton.setStyleSheet(buttonStyle)
self.shapeButton.setEnabled(False)
self.applyButton = QToolButton(self)
self.applyButton.setText(self.tr("Apply"))
self.applyButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self.applyButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.applyButton.setEnabled(False)
self.applyButton.clicked.connect(self._saveItem) self.applyButton.clicked.connect(self._saveItem)
# Assemble # Assemble
@@ -407,8 +427,8 @@ class _StatusPage(NFixedPage):
self.editBox = QHBoxLayout() self.editBox = QHBoxLayout()
self.editBox.addWidget(self.editName, 1) self.editBox.addWidget(self.editName, 1)
self.editBox.addWidget(self.colButton, 0) self.editBox.addWidget(self.colorButton, 0)
self.editBox.addWidget(self.shapeList, 0) self.editBox.addWidget(self.shapeButton, 0)
self.editBox.addWidget(self.applyButton, 0) self.editBox.addWidget(self.applyButton, 0)
self.mainBox = QVBoxLayout() self.mainBox = QVBoxLayout()
@@ -416,14 +436,15 @@ class _StatusPage(NFixedPage):
self.mainBox.addLayout(self.editBox, 0) self.mainBox.addLayout(self.editBox, 0)
self.innerBox = QHBoxLayout() self.innerBox = QHBoxLayout()
self.innerBox.addLayout(self.mainBox) self.innerBox.addLayout(self.mainBox, 1)
self.innerBox.addLayout(self.listControls) self.innerBox.addLayout(self.listControls, 0)
self.outerBox = QVBoxLayout() self.outerBox = QVBoxLayout()
self.outerBox.addWidget(self.pageTitle) self.outerBox.addWidget(self.pageTitle, 0)
self.outerBox.addLayout(self.innerBox) self.outerBox.addLayout(self.innerBox, 1)
self.setCentralLayout(self.outerBox) self.setCentralLayout(self.outerBox)
self._setButtonIcons()
return return
@@ -461,7 +482,7 @@ class _StatusPage(NFixedPage):
"""Open a dialog to select the status icon colour.""" """Open a dialog to select the status icon colour."""
if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid(): if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
self._color = color self._color = color
self._setColButton(color) self._setButtonIcons()
return return
@pyqtSlot() @pyqtSlot()
@@ -494,13 +515,11 @@ 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())
selected = self.shapeList.currentData() icon = NWStatus.createIcon(self._iPx, self._color, self._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.color = self._color
entry.shape = shape entry.shape = self._shape
entry.icon = icon entry.icon = icon
item.setText(self.C_LABEL, name) item.setText(self.C_LABEL, name)
@@ -518,27 +537,27 @@ 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._color = entry.color self._color = entry.color
self._setColButton(entry.color) self._shape = entry.shape
self._setButtonIcons()
self.editName.setText(entry.name) self.editName.setText(entry.name)
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.colorButton.setEnabled(True)
self.shapeList.setEnabled(True) self.shapeButton.setEnabled(True)
self.applyButton.setEnabled(True) self.applyButton.setEnabled(True)
else: else:
self._color = QColor(100, 100, 100) self._color = QColor(100, 100, 100)
self._setColButton(self._color) self._shape = nwStatusShape.SQUARE
self._setButtonIcons()
self.editName.setText("") self.editName.setText("")
self.shapeList.setCurrentIndex(0)
self.editName.setEnabled(False) self.editName.setEnabled(False)
self.colButton.setEnabled(False) self.colorButton.setEnabled(False)
self.shapeList.setEnabled(False) self.shapeButton.setEnabled(False)
self.applyButton.setEnabled(False) self.applyButton.setEnabled(False)
return return
@@ -546,6 +565,12 @@ class _StatusPage(NFixedPage):
# Internal Functions # Internal Functions
## ##
def _selectShape(self, shape: nwStatusShape) -> None:
"""Set the current shape."""
self._shape = shape
self._setButtonIcons()
return
def _addItem(self, key: str | None, entry: StatusEntry) -> None: def _addItem(self, key: str | None, entry: StatusEntry) -> None:
"""Add a status item to the list.""" """Add a status item to the list."""
item = QTreeWidgetItem() item = QTreeWidgetItem()
@@ -585,12 +610,11 @@ class _StatusPage(NFixedPage):
else: else:
return self.trCountMore.format(count) return self.trCountMore.format(count)
def _setColButton(self, color: QColor) -> None: def _setButtonIcons(self) -> None:
"""Set the colour of the colour button.""" """Set the colour of the colour button."""
pixmap = QPixmap(self._iPx, self._iPx) icon = NWStatus.createIcon(self._iPx, self._color, nwStatusShape.SQUARE)
pixmap.fill(color) self.colorButton.setIcon(icon)
self.colButton.setIcon(QIcon(pixmap)) self.shapeButton.setIcon(self._icons[self._shape])
self.colButton.setIconSize(pixmap.rect().size())
return return
# END Class _StatusPage # END Class _StatusPage
@@ -598,8 +622,8 @@ class _StatusPage(NFixedPage):
class _ReplacePage(NFixedPage): class _ReplacePage(NFixedPage):
COL_KEY = 0 C_KEY = 0
COL_REPL = 1 C_REPL = 1
def __init__(self, parent: QWidget) -> None: def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent) super().__init__(parent=parent)
@@ -621,7 +645,7 @@ class _ReplacePage(NFixedPage):
# List Box # List Box
self.listBox = QTreeWidget(self) self.listBox = QTreeWidget(self)
self.listBox.setHeaderLabels([self.tr("Keyword"), self.tr("Replace With")]) self.listBox.setHeaderLabels([self.tr("Keyword"), self.tr("Replace With")])
self.listBox.setColumnWidth(self.COL_KEY, wCol0) self.listBox.setColumnWidth(self.C_KEY, wCol0)
self.listBox.setIndentation(0) self.listBox.setIndentation(0)
self.listBox.itemSelectionChanged.connect(self._selectedItem) self.listBox.itemSelectionChanged.connect(self._selectedItem)
@@ -629,7 +653,7 @@ class _ReplacePage(NFixedPage):
newItem = QTreeWidgetItem(["<%s>" % aKey, aVal]) newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
self.listBox.addTopLevelItem(newItem) self.listBox.addTopLevelItem(newItem)
self.listBox.sortByColumn(self.COL_KEY, Qt.SortOrder.AscendingOrder) self.listBox.sortByColumn(self.C_KEY, Qt.SortOrder.AscendingOrder)
self.listBox.setSortingEnabled(True) self.listBox.setSortingEnabled(True)
# List Controls # List Controls
@@ -649,7 +673,9 @@ class _ReplacePage(NFixedPage):
self.editValue.setEnabled(False) self.editValue.setEnabled(False)
self.editValue.setMaxLength(80) self.editValue.setMaxLength(80)
self.applyButton = QPushButton(self.tr("Apply"), self) self.applyButton = QToolButton(self)
self.applyButton.setText(self.tr("Apply"))
self.applyButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
self.applyButton.clicked.connect(self._saveEntry) self.applyButton.clicked.connect(self._saveEntry)
# Assemble # Assemble
@@ -664,8 +690,8 @@ class _ReplacePage(NFixedPage):
self.editBox.addWidget(self.applyButton, 0) self.editBox.addWidget(self.applyButton, 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)
@@ -692,11 +718,9 @@ class _ReplacePage(NFixedPage):
"""Extract the list from the widget.""" """Extract the list from the widget."""
new = {} new = {}
for n in range(self.listBox.topLevelItemCount()): for n in range(self.listBox.topLevelItemCount()):
if tItem := self.listBox.topLevelItem(n): if item := self.listBox.topLevelItem(n):
aKey = self._stripNotAllowed(tItem.text(0)) if key := self._stripNotAllowed(item.text(self.C_KEY)):
aVal = tItem.text(1) new[key] = item.text(self.C_REPL)
if len(aKey) > 0:
new[aKey] = aVal
return new return new
def columnWidth(self) -> int: def columnWidth(self) -> int:
@@ -712,11 +736,9 @@ class _ReplacePage(NFixedPage):
"""Extract the details from the selected item and populate the """Extract the details from the selected item and populate the
edit form. edit form.
""" """
if selItem := self._getSelectedItem(): if item := self._getSelectedItem():
editKey = self._stripNotAllowed(selItem.text(0)) self.editKey.setText(self._stripNotAllowed(item.text(self.C_KEY)))
editVal = selItem.text(1) self.editValue.setText(item.text(self.C_REPL))
self.editKey.setText(editKey)
self.editValue.setText(editVal)
self.editKey.setEnabled(True) self.editKey.setEnabled(True)
self.editValue.setEnabled(True) self.editValue.setEnabled(True)
self.editKey.selectAll() self.editKey.selectAll()
@@ -726,33 +748,27 @@ class _ReplacePage(NFixedPage):
@pyqtSlot() @pyqtSlot()
def _saveEntry(self) -> None: def _saveEntry(self) -> None:
"""Save the form data into the list widget.""" """Save the form data into the list widget."""
if selItem := self._getSelectedItem(): if item := self._getSelectedItem():
newKey = self.editKey.text() key = self._stripNotAllowed(self.editKey.text())
newVal = self.editValue.text() value = self.editValue.text()
saveKey = self._stripNotAllowed(newKey) if key and value:
if len(saveKey) > 0 and len(newVal) > 0: item.setText(self.C_KEY, f"<{key}>")
selItem.setText(self.COL_KEY, "<%s>" % saveKey) item.setText(self.C_REPL, value)
selItem.setText(self.COL_REPL, newVal)
self.editKey.clear()
self.editValue.clear()
self.editKey.setEnabled(False)
self.editValue.setEnabled(False)
self.listBox.clearSelection()
self._changed = True self._changed = True
return return
@pyqtSlot() @pyqtSlot()
def _addEntry(self) -> None: def _addEntry(self) -> None:
"""Add a new list entry.""" """Add a new list entry."""
saveKey = "<keyword%d>" % (self.listBox.topLevelItemCount() + 1) key = f"<keyword{self.listBox.topLevelItemCount() + 1:d}>"
self.listBox.addTopLevelItem(QTreeWidgetItem([saveKey, ""])) self.listBox.addTopLevelItem(QTreeWidgetItem([key, ""]))
return return
@pyqtSlot() @pyqtSlot()
def _delEntry(self) -> None: def _delEntry(self) -> None:
"""Delete the selected entry.""" """Delete the selected entry."""
if selItem := self._getSelectedItem(): if item := self._getSelectedItem():
self.listBox.takeTopLevelItem(self.listBox.indexOfTopLevelItem(selItem)) self.listBox.takeTopLevelItem(self.listBox.indexOfTopLevelItem(item))
self._changed = True self._changed = True
return return