diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index e9094c8b..f12220e5 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -46,7 +46,7 @@ from PyQt5.QtGui import ( ) from PyQt5.QtWidgets import ( QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu, - QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QWidget, + QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout, QWidget, qApp ) @@ -83,6 +83,8 @@ class GuiDocEditor(QPlainTextEdit): novelStructureChanged = pyqtSignal() novelItemMetaChanged = pyqtSignal(str) spellCheckStateChanged = pyqtSignal(bool) + closeDocumentRequest = pyqtSignal() + toggleFocusModeRequest = pyqtSignal() def __init__(self, mainGui: GuiMain) -> None: super().__init__(parent=mainGui) @@ -135,6 +137,10 @@ class GuiDocEditor(QPlainTextEdit): self.docHeader = GuiDocEditHeader(self) self.docFooter = GuiDocEditFooter(self) self.docSearch = GuiDocEditSearch(self) + self.docToolBar = GuiDocToolBar(self) + + # Connect Signals + self.docHeader.closeDocumentRequest.connect(self._closeCurrentDocument) # Context Menu self.setContextMenuPolicy(Qt.CustomContextMenu) @@ -248,6 +254,7 @@ class GuiDocEditor(QPlainTextEdit): self.docSearch.updateTheme() self.docHeader.updateTheme() self.docFooter.updateTheme() + self.docToolBar.updateTheme() return def updateSyntaxColours(self) -> None: @@ -514,6 +521,7 @@ class GuiDocEditor(QPlainTextEdit): fY = wH - fH - tB - sH self.docHeader.setGeometry(tB, tB, tW, tH) self.docFooter.setGeometry(tB, fY, tW, fH) + self.docToolBar.move(0, tH) rH = 0 if self.docSearch.isVisible(): @@ -857,6 +865,7 @@ class GuiDocEditor(QPlainTextEdit): self.docSearch.closeSearch() return self.docSearch.isVisible() + @pyqtSlot() def toggleSearch(self) -> None: """Toggle the visibility of the search box.""" if self.docSearch.isVisible(): @@ -1179,6 +1188,12 @@ class GuiDocEditor(QPlainTextEdit): return + @pyqtSlot() + def _closeCurrentDocument(self) -> None: + """Close the document. Forwarded to the main Gui.""" + self.closeDocumentRequest.emit() + return + ## # Search & Replace ## @@ -2072,6 +2087,77 @@ class BackgroundWordCounterSignals(QObject): # END Class BackgroundWordCounterSignals +# =============================================================================================== # +# The Formatting and Options Fold Out Menu +# Only used by DocEditor, and is opened by the first button in the header +# =============================================================================================== # + +class GuiDocToolBar(QWidget): + + def __init__(self, docEditor: GuiDocEditor) -> None: + super().__init__(parent=docEditor) + + logger.debug("Create: GuiDocToolBar") + + cM = CONFIG.pxInt(4) + tPx = int(0.8*SHARED.theme.fontPixelSize) + iconSize = QSize(tPx, tPx) + self.setContentsMargins(0, 0, 0, 0) + + # General Buttons + # =============== + + self.tbSticky = QToolButton(self) + self.tbSticky.setIconSize(iconSize) + + self.tbEdit = QToolButton(self) + self.tbEdit.setIconSize(iconSize) + + # Assemble + # ======== + + self.outerBox = QVBoxLayout() + self.outerBox.addWidget(self.tbSticky) + self.outerBox.addWidget(self.tbEdit) + self.outerBox.setContentsMargins(cM, cM, cM, cM) + self.outerBox.setSpacing(cM) + + self.setLayout(self.outerBox) + self.updateTheme() + + logger.debug("Ready: GuiDocToolBar") + + return + + def updateTheme(self) -> None: + """Initialise GUI elements that depend on specific settings.""" + palette = QPalette() + palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack)) + palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText)) + palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText)) + + self.setPalette(palette) + + # qPalette = self.palette() + # qPalette.setBrush(QPalette.Window, qPalette.base()) + # self.setPalette(qPalette) + + # fadeCol = qPalette.text().color() + # buttonStyle = ( + # "QToolButton {{padding: {0}px; border: none; background: transparent;}} " + # "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" + # ).format(CONFIG.pxInt(4), fadeCol.red(), fadeCol.green(), fadeCol.blue()) + # buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}" + # self.tbEdit.setStyleSheet(buttonStyle) + + self.tbSticky.setIcon(SHARED.theme.getIcon("sticky-off")) + self.tbEdit.setIcon(SHARED.theme.getIcon("edit")) + + return + +# END Class GuiDocToolBar + + # =============================================================================================== # # The Embedded Document Search/Replace Feature # Only used by DocEditor, and is at a fixed position in the QTextEdit's viewport @@ -2487,6 +2573,9 @@ class GuiDocEditSearch(QFrame): class GuiDocEditHeader(QWidget): + toggleToolBarRequest = pyqtSignal() + closeDocumentRequest = pyqtSignal() + def __init__(self, docEditor: GuiDocEditor) -> None: super().__init__(parent=docEditor) @@ -2499,6 +2588,7 @@ class GuiDocEditHeader(QWidget): fPx = int(0.9*SHARED.theme.fontPixelSize) hSp = CONFIG.pxInt(6) + iconSize = QSize(fPx, fPx) # Main Widget Settings self.setAutoFillBackground(True) @@ -2518,46 +2608,46 @@ class GuiDocEditHeader(QWidget): self.itemTitle.setFont(lblFont) # Buttons - self.editButton = QToolButton(self) - self.editButton.setContentsMargins(0, 0, 0, 0) - self.editButton.setIconSize(QSize(fPx, fPx)) - self.editButton.setFixedSize(fPx, fPx) - self.editButton.setToolButtonStyle(Qt.ToolButtonIconOnly) - self.editButton.setVisible(False) - self.editButton.setToolTip(self.tr("Edit document label")) - self.editButton.clicked.connect(self._editDocument) + self.tbButton = QToolButton(self) + self.tbButton.setContentsMargins(0, 0, 0, 0) + self.tbButton.setIconSize(iconSize) + self.tbButton.setFixedSize(fPx, fPx) + self.tbButton.setToolButtonStyle(Qt.ToolButtonIconOnly) + self.tbButton.setVisible(False) + self.tbButton.setToolTip(self.tr("Toggle Tool Bar")) + self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit()) self.searchButton = QToolButton(self) self.searchButton.setContentsMargins(0, 0, 0, 0) - self.searchButton.setIconSize(QSize(fPx, fPx)) + self.searchButton.setIconSize(iconSize) self.searchButton.setFixedSize(fPx, fPx) self.searchButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.searchButton.setVisible(False) - self.searchButton.setToolTip(self.tr("Search document")) - self.searchButton.clicked.connect(self._searchDocument) + self.searchButton.setToolTip(self.tr("Search")) + self.searchButton.clicked.connect(self.docEditor.toggleSearch) self.minmaxButton = QToolButton(self) self.minmaxButton.setContentsMargins(0, 0, 0, 0) - self.minmaxButton.setIconSize(QSize(fPx, fPx)) + self.minmaxButton.setIconSize(iconSize) self.minmaxButton.setFixedSize(fPx, fPx) self.minmaxButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.minmaxButton.setVisible(False) self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode")) - self.minmaxButton.clicked.connect(self._minmaxDocument) + self.minmaxButton.clicked.connect(lambda: self.docEditor.toggleFocusModeRequest.emit()) self.closeButton = QToolButton(self) self.closeButton.setContentsMargins(0, 0, 0, 0) - self.closeButton.setIconSize(QSize(fPx, fPx)) + self.closeButton.setIconSize(iconSize) self.closeButton.setFixedSize(fPx, fPx) self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.closeButton.setVisible(False) - self.closeButton.setToolTip(self.tr("Close the document")) + self.closeButton.setToolTip(self.tr("Close")) self.closeButton.clicked.connect(self._closeDocument) # Assemble Layout self.outerBox = QHBoxLayout() self.outerBox.setSpacing(hSp) - self.outerBox.addWidget(self.editButton, 0) + self.outerBox.addWidget(self.tbButton, 0) self.outerBox.addWidget(self.searchButton, 0) self.outerBox.addWidget(self.itemTitle, 1) self.outerBox.addWidget(self.minmaxButton, 0) @@ -2583,7 +2673,7 @@ class GuiDocEditHeader(QWidget): def updateTheme(self) -> None: """Update theme elements.""" - self.editButton.setIcon(SHARED.theme.getIcon("edit")) + self.tbButton.setIcon(SHARED.theme.getIcon("menu")) self.searchButton.setIcon(SHARED.theme.getIcon("search")) self.minmaxButton.setIcon(SHARED.theme.getIcon("maximise")) self.closeButton.setIcon(SHARED.theme.getIcon("close")) @@ -2593,7 +2683,7 @@ class GuiDocEditHeader(QWidget): "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}" ).format(*SHARED.theme.colText) - self.editButton.setStyleSheet(buttonStyle) + self.tbButton.setStyleSheet(buttonStyle) self.searchButton.setStyleSheet(buttonStyle) self.minmaxButton.setStyleSheet(buttonStyle) self.closeButton.setStyleSheet(buttonStyle) @@ -2623,7 +2713,7 @@ class GuiDocEditHeader(QWidget): self._docHandle = tHandle if tHandle is None: self.itemTitle.setText("") - self.editButton.setVisible(False) + self.tbButton.setVisible(False) self.searchButton.setVisible(False) self.closeButton.setVisible(False) self.minmaxButton.setVisible(False) @@ -2645,7 +2735,7 @@ class GuiDocEditHeader(QWidget): return False self.itemTitle.setText(nwItem.itemName) - self.editButton.setVisible(True) + self.tbButton.setVisible(True) self.searchButton.setVisible(True) self.closeButton.setVisible(True) self.minmaxButton.setVisible(True) @@ -2667,34 +2757,16 @@ class GuiDocEditHeader(QWidget): # Private Slots ## - @pyqtSlot() - def _editDocument(self) -> None: - """Open the edit item dialog from the main GUI.""" - self.mainGui.editItemLabel(self._docHandle) - return - - @pyqtSlot() - def _searchDocument(self) -> None: - """Toggle the visibility of the search box.""" - self.docEditor.toggleSearch() - return - @pyqtSlot() def _closeDocument(self) -> None: """Trigger the close editor on the main window.""" - self.mainGui.closeDocEditor() - self.editButton.setVisible(False) + self.closeDocumentRequest.emit() + self.tbButton.setVisible(False) self.searchButton.setVisible(False) self.closeButton.setVisible(False) self.minmaxButton.setVisible(False) return - @pyqtSlot() - def _minmaxDocument(self) -> None: - """Switch on or off Focus Mode.""" - self.mainGui.toggleFocusMode() - return - ## # Events ## diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 18dfdbc5..9aff4eee 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -705,7 +705,7 @@ class GuiDocViewHeader(QWidget): self.backButton.setFixedSize(fPx, fPx) self.backButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.backButton.setVisible(False) - self.backButton.setToolTip(self.tr("Go backward")) + self.backButton.setToolTip(self.tr("Go Backward")) self.backButton.clicked.connect(self.docViewer.navBackward) self.forwardButton = QToolButton(self) @@ -714,7 +714,7 @@ class GuiDocViewHeader(QWidget): self.forwardButton.setFixedSize(fPx, fPx) self.forwardButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.forwardButton.setVisible(False) - self.forwardButton.setToolTip(self.tr("Go forward")) + self.forwardButton.setToolTip(self.tr("Go Forward")) self.forwardButton.clicked.connect(self.docViewer.navForward) self.refreshButton = QToolButton(self) @@ -723,7 +723,7 @@ class GuiDocViewHeader(QWidget): self.refreshButton.setFixedSize(fPx, fPx) self.refreshButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.refreshButton.setVisible(False) - self.refreshButton.setToolTip(self.tr("Reload the document")) + self.refreshButton.setToolTip(self.tr("Reload")) self.refreshButton.clicked.connect(self._refreshDocument) self.closeButton = QToolButton(self) @@ -732,7 +732,7 @@ class GuiDocViewHeader(QWidget): self.closeButton.setFixedSize(fPx, fPx) self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.closeButton.setVisible(False) - self.closeButton.setToolTip(self.tr("Close the document")) + self.closeButton.setToolTip(self.tr("Close")) self.closeButton.clicked.connect(self._closeDocument) # Assemble Layout