""" novelWriter – GUI Quotes Dialog =============================== File History: Created: 2020-06-18 [0.9.0] GuiQuoteSelect This file is a part of novelWriter Copyright (C) 2021 Veronica Berglyd Olsen and novelWriter contributors 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 . """ # noqa from __future__ import annotations import logging from PyQt6.QtCore import QSize, pyqtSlot from PyQt6.QtGui import QFontMetrics from PyQt6.QtWidgets import ( QDialogButtonBox, QFrame, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QVBoxLayout, QWidget ) from novelwriter import SHARED from novelwriter.constants import nwQuotes, trConst from novelwriter.enum import nwStandardButton from novelwriter.extensions.modified import NDialog from novelwriter.types import ( QtAccepted, QtAlignCenter, QtAlignTop, QtRoleAccept, QtRoleReject, QtUserRole ) logger = logging.getLogger(__name__) class GuiQuoteSelect(NDialog): """GUI: Quote Selector Dialog.""" _selected = "" D_KEY = QtUserRole def __init__(self, parent: QWidget, current: str = '"') -> None: super().__init__(parent=parent) logger.debug("Create: GuiQuoteSelect") self.setObjectName("GuiQuoteSelect") self.setWindowTitle(self.tr("Select Quote Style")) self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() self.labelBox = QVBoxLayout() self._selected = current lblFont = self.font() lblFont.setPointSizeF(4*lblFont.pointSizeF()) metrics = QFontMetrics(self.font()) # Preview Label self.previewLabel = QLabel(current, self) self.previewLabel.setFont(lblFont) self.previewLabel.setFixedSize(QSize(4*metrics.maxWidth(), 5*metrics.height())) self.previewLabel.setAlignment(QtAlignCenter) self.previewLabel.setFrameStyle(QFrame.Shape.Box | QFrame.Shadow.Plain) # Quote Symbols self.listBox = QListWidget(self) self.listBox.itemSelectionChanged.connect(self._selectedSymbol) minSize = 100 for sKey, sLabel in nwQuotes.SYMBOLS.items(): text = f"[ {sKey} ] {trConst(sLabel)}" minSize = max(minSize, metrics.boundingRect(text).width()) qtItem = QListWidgetItem(text) qtItem.setData(self.D_KEY, sKey) self.listBox.addItem(qtItem) if sKey == current: self.listBox.setCurrentItem(qtItem) self.listBox.setMinimumWidth(minSize + 40) self.listBox.setMinimumHeight(150) # Buttons self.btnOk = SHARED.theme.getStandardButton(nwStandardButton.OK, self) self.btnOk.clicked.connect(self.accept) self.btnCancel = SHARED.theme.getStandardButton(nwStandardButton.CANCEL, self) self.btnCancel.clicked.connect(self.reject) self.btnBox = QDialogButtonBox(self) self.btnBox.addButton(self.btnOk, QtRoleAccept) self.btnBox.addButton(self.btnCancel, QtRoleReject) # Assemble self.labelBox.addWidget(self.previewLabel, 0, QtAlignTop) self.labelBox.addStretch(1) self.innerBox.addLayout(self.labelBox) self.innerBox.addWidget(self.listBox) self.outerBox.addLayout(self.innerBox) self.outerBox.addWidget(self.btnBox) self.setLayout(self.outerBox) logger.debug("Ready: GuiQuoteSelect") def __del__(self) -> None: # pragma: no cover logger.debug("Delete: GuiQuoteSelect") @property def selectedQuote(self) -> str: """Return the selected quote symbol.""" return self._selected @classmethod def getQuote(cls, parent: QWidget, current: str = "") -> tuple[str, bool]: """Pop the dialog and return the result.""" dialog = cls(parent, current=current) dialog.exec() quote = dialog._selected accepted = dialog.result() == QtAccepted dialog.softDelete() return quote, accepted ## # Private Slots ## @pyqtSlot() def _selectedSymbol(self) -> None: """Update the preview label and the selected quote style.""" if items := self.listBox.selectedItems(): quote = items[0].data(self.D_KEY) self.previewLabel.setText(quote) self._selected = quote