Add search bar to preferences

This commit is contained in:
Veronica Berglyd Olsen
2024-01-08 21:08:33 +01:00
parent 1fbd50334d
commit 671d7130e1
2 changed files with 96 additions and 13 deletions
+63 -7
View File
@@ -26,12 +26,12 @@ from __future__ import annotations
import logging
from PyQt5.QtGui import QCloseEvent, QFont
from PyQt5.QtGui import QCloseEvent, QColor, QFont, QKeyEvent, QKeySequence, QPalette
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
QAbstractButton, QDialog, QHBoxLayout, QVBoxLayout, QWidget, QComboBox,
QSpinBox, QPushButton, QDialogButtonBox, QLineEdit, QFileDialog,
QFontDialog, QDoubleSpinBox, qApp
QAbstractButton, QComboBox, QCompleter, QDialog, QDialogButtonBox,
QDoubleSpinBox, QFileDialog, QFontDialog, QHBoxLayout, QLabel, QLineEdit,
QPushButton, QSpinBox, QVBoxLayout, QWidget, qApp
)
from novelwriter import CONFIG, SHARED
@@ -58,37 +58,80 @@ class GuiPreferences(QDialog):
self.setMinimumSize(CONFIG.pxInt(600), CONFIG.pxInt(500))
self.resize(*CONFIG.preferencesWinSize)
# Title
font = self.font()
font.setPointSizeF(1.5*SHARED.theme.fontPointSize)
palette = self.palette()
palette.setColor(QPalette.ColorRole.WindowText, QColor(*SHARED.theme.helpText))
self.titleLabel = QLabel(self.tr("Preferences"), self)
self.titleLabel.setFont(font)
self.titleLabel.setPalette(palette)
self.titleLabel.setIndent(CONFIG.pxInt(4))
# SideBar
self.sidebar = NPagedSideBar(self)
self.sidebar.setLabelColor(SHARED.theme.helpText)
self.sidebar.addLabel(self.tr("Preferences"))
self.sidebar.buttonClicked.connect(self._sidebarClicked)
# Search Box
self.searchText = QLineEdit(self)
self.searchText.setPlaceholderText(self.tr("Search"))
self.searchText.setMinimumWidth(CONFIG.pxInt(200))
self.searchAction = self.searchText.addAction(
SHARED.theme.getIcon("search"), QLineEdit.ActionPosition.TrailingPosition
)
self.searchAction.triggered.connect(self._gotoSearch)
self.searchBox = QHBoxLayout()
self.searchBox.addWidget(self.titleLabel)
self.searchBox.addStretch(1)
self.searchBox.addWidget(self.searchText, 1)
# Form
self.mainForm = NScrollableForm(self)
self.mainForm.setHelpTextStyle(SHARED.theme.helpText)
# Buttons
self.buttonBox = QDialogButtonBox(
QDialogButtonBox.Apply | QDialogButtonBox.Save | QDialogButtonBox.Close
QDialogButtonBox.StandardButton.Apply
| QDialogButtonBox.StandardButton.Save
| QDialogButtonBox.StandardButton.Close
)
self.buttonBox.clicked.connect(self._dialogButtonClicked)
# Assemble
self.mainSearch = QVBoxLayout()
self.mainSearch.addItem(self.searchBox)
self.mainSearch.addWidget(self.mainForm)
self.mainBox = QHBoxLayout()
self.mainBox.addWidget(self.sidebar)
# self.mainBox.addLayout(self.mainSearch)
self.mainBox.addWidget(self.mainForm)
self.mainBox.setContentsMargins(0, 0, 0, 0)
self.outerBox = QVBoxLayout()
self.outerBox.addLayout(self.searchBox)
self.outerBox.addLayout(self.mainBox)
self.outerBox.addWidget(self.buttonBox)
self.outerBox.setSpacing(CONFIG.pxInt(8))
self.setLayout(self.outerBox)
self.setSizeGripEnabled(True)
# Build Form
self.buildForm()
# Populate Search
self.searchCompleter = QCompleter(self.mainForm.labels, self)
self.searchCompleter.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
self.searchCompleter.setFilterMode(Qt.MatchFlag.MatchContains)
self.searchCompleter.activated.connect(self._gotoSearch)
self.searchText.setCompleter(self.searchCompleter)
logger.debug("Ready: GuiPreferences")
return
@@ -768,9 +811,17 @@ class GuiPreferences(QDialog):
logger.debug("Close: GuiPreferences")
self._saveWindowSize()
event.accept()
qApp.processEvents()
self.deleteLater()
return
def keyPressEvent(self, event: QKeyEvent) -> None:
"""Overload keyPressEvent to block enter key to save."""
if event.matches(QKeySequence.Cancel):
self.reject()
event.ignore()
return
##
# Private Slots
##
@@ -794,6 +845,12 @@ class GuiPreferences(QDialog):
self.mainForm.scrollToSection(section)
return
@pyqtSlot()
def _gotoSearch(self) -> None:
"""Go to the setting indicated by the search text."""
self.mainForm.scrollToLabel(self.searchText.text().strip())
return
@pyqtSlot()
def _selectGuiFont(self) -> None:
"""Open the QFontDialog and set a font for the font style."""
@@ -972,7 +1029,6 @@ class GuiPreferences(QDialog):
# Finalise
CONFIG.saveConfig()
self.newPreferencesReady.emit(needsRestart, refreshTree, updateTheme, updateSyntax)
qApp.processEvents()
return
+33 -6
View File
@@ -3,7 +3,9 @@ novelWriter Custom Widget: Config Layout
==========================================
File History:
Created: 2020-05-03 [0.4.5]
Created: 2020-05-03 [0.4.5] NConfigLayout, NHelpLabel
Created: 2023-05-23 [2.1b1] NSimpleLayout
Created: 2024-01-08 [2.3b1] NScrollableForm
This file is a part of novelWriter
Copyright 20182024, Veronica Berglyd Olsen
@@ -45,6 +47,7 @@ class NScrollableForm(QScrollArea):
self._fontScale = FONT_SCALE
self._sections: dict[int, QLabel] = {}
self._editable: dict[str, NHelpLabel] = {}
self._index: dict[str, QWidget] = {}
self._layout = QVBoxLayout()
self._layout.setSpacing(CONFIG.pxInt(12))
@@ -59,6 +62,18 @@ class NScrollableForm(QScrollArea):
return
##
# Properties
##
@property
def labels(self) -> list[str]:
return list(self._index.keys())
##
# Setters
##
def setHelpTextStyle(self, color: QColor | list | tuple, scale: float = FONT_SCALE) -> None:
"""Set the text color for the help text."""
self._helpCol = color if isinstance(color, QColor) else QColor(*color)
@@ -71,18 +86,24 @@ class NScrollableForm(QScrollArea):
qHelp.setText(text)
return
def finalise(self) -> None:
"""Finalise the layout when the form is built."""
self._layout.addStretch(1)
return
##
# Methods
##
def scrollToSection(self, identifier: int, offset: int = 50) -> None:
def scrollToSection(self, identifier: int) -> None:
"""Scroll to the requested section identifier."""
if identifier in self._sections:
yPos = self._sections[identifier].pos().y() - CONFIG.pxInt(8)
self.verticalScrollBar().setValue(yPos)
return
def scrollToLabel(self, label: str) -> None:
"""Scroll to the requested label."""
if label in self._index:
yPos = self._index[label].pos().y() - CONFIG.pxInt(8)
self.verticalScrollBar().setValue(yPos)
return
def addGroupLabel(self, label: str, identifier: int) -> None:
"""Add a text label to separate groups of settings."""
hM = CONFIG.pxInt(4)
@@ -124,9 +145,15 @@ class NScrollableForm(QScrollArea):
row.addWidget(button)
self._layout.addLayout(row)
self._index[label.strip()] = widget
return
def finalise(self) -> None:
"""Finalise the layout when the form is built."""
self._layout.addStretch(1)
return
# END Class NScrollableForm