From bcb0437598e20019bcfc88b599780caad360c077 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 12 Jan 2025 10:54:40 -0500 Subject: [PATCH] Support tearing off tags menu * Closes #11649 - tags menu can be torn off to set and unset tags without having to dive into the context menu every time. * Tags menu will hide when database is locked or view is switched away from the main database view (eg, settings) --- src/gui/MainWindow.cpp | 14 +++++++++++--- src/gui/MainWindow.ui | 3 +++ src/gui/styles/base/BaseStyle.cpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3a19f06683..2b0be4b1ab 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -820,15 +820,15 @@ void MainWindow::updateSetTagsMenu() if (dbWidget) { // Enumerate tags applied to the selected entries QSet selectedTags; - for (auto entry : dbWidget->entryView()->selectedEntries()) { - for (auto tag : entry->tagList()) { + for (const auto entry : dbWidget->entryView()->selectedEntries()) { + for (const auto& tag : entry->tagList()) { selectedTags.insert(tag); } } // Add known database tags as actions and set checked if // a selected entry has that tag - for (auto tag : dbWidget->database()->tagList()) { + for (const auto& tag : dbWidget->database()->tagList()) { auto action = m_ui->menuTags->addAction(icons()->icon("tag"), tag); action->setCheckable(true); action->setChecked(selectedTags.contains(tag)); @@ -938,6 +938,14 @@ void MainWindow::updateMenuActionState() m_ui->menuEntryCopyAttribute->setEnabled(singleEntryOrEditing); m_ui->menuEntryTotp->setEnabled(singleEntrySelected); m_ui->menuTags->setEnabled(multiEntrySelected); + // Handle tear-off tags menu + if (m_ui->menuTags->menuAction()->isVisible()) { + if (!databaseUnlocked) { + m_ui->menuTags->hideTearOffMenu(); + } else { + updateSetTagsMenu(); + } + } m_ui->actionEntryAutoType->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled()); m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled()); m_ui->actionEntryAutoTypeSequence->setText(singleEntrySelected diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index c84727c3e8..df1f659539 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -314,6 +314,9 @@ + + true + Tags diff --git a/src/gui/styles/base/BaseStyle.cpp b/src/gui/styles/base/BaseStyle.cpp index 9cb844d700..8fa8f64bbc 100644 --- a/src/gui/styles/base/BaseStyle.cpp +++ b/src/gui/styles/base/BaseStyle.cpp @@ -2636,7 +2636,21 @@ void BaseStyle::drawControl(ControlElement element, } break; } + case CE_MenuTearoff: { + if (option->state & State_Selected) { + painter->fillRect(option->rect, option->palette.brush(QPalette::Highlight)); + painter->setPen(QPen(option->palette.highlightedText().color(), 1, Qt::DashLine)); + } else { + painter->fillRect(option->rect, option->palette.brush(QPalette::Button)); + painter->setPen(QPen(option->palette.buttonText().color(), 1, Qt::DashLine)); + } + painter->drawLine(option->rect.x() + 2, + option->rect.y() + option->rect.height() / 2, + option->rect.x() + option->rect.width() - 4, + option->rect.y() + option->rect.height() / 2); + break; + } case CE_MenuItem: { auto menuItem = qstyleoption_cast(option); if (!menuItem)