mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-03-03 03:39:30 -05:00
Support tearing off tags menu (#11652)
* 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)
This commit is contained in:
parent
d6e726a9cf
commit
e4bb80b96c
@ -817,26 +817,45 @@ void MainWindow::updateCopyAttributesMenu()
|
|||||||
|
|
||||||
void MainWindow::updateSetTagsMenu()
|
void MainWindow::updateSetTagsMenu()
|
||||||
{
|
{
|
||||||
// Remove all existing actions
|
auto actionForTag = [](const QMenu* menu, const QString& tag) -> QAction* {
|
||||||
m_ui->menuTags->clear();
|
for (const auto action : menu->actions()) {
|
||||||
|
if (action->text() == tag) {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
auto dbWidget = m_ui->tabWidget->currentDatabaseWidget();
|
auto dbWidget = m_ui->tabWidget->currentDatabaseWidget();
|
||||||
if (dbWidget) {
|
if (dbWidget) {
|
||||||
// Enumerate tags applied to the selected entries
|
// Enumerate tags applied to the selected entries
|
||||||
QSet<QString> selectedTags;
|
QSet<QString> selectedTags;
|
||||||
for (auto entry : dbWidget->entryView()->selectedEntries()) {
|
for (const auto entry : dbWidget->entryView()->selectedEntries()) {
|
||||||
for (auto tag : entry->tagList()) {
|
for (const auto& tag : entry->tagList()) {
|
||||||
selectedTags.insert(tag);
|
selectedTags.insert(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add known database tags as actions and set checked if
|
// Add known database tags as actions and set checked if
|
||||||
// a selected entry has that tag
|
// a selected entry has that tag
|
||||||
for (auto tag : dbWidget->database()->tagList()) {
|
const auto tagList = dbWidget->database()->tagList();
|
||||||
auto action = m_ui->menuTags->addAction(icons()->icon("tag"), tag);
|
for (const auto& tag : tagList) {
|
||||||
action->setCheckable(true);
|
auto action = actionForTag(m_ui->menuTags, tag);
|
||||||
action->setChecked(selectedTags.contains(tag));
|
if (action) {
|
||||||
m_setTagsMenuActions->addAction(action);
|
action->setChecked(selectedTags.contains(tag));
|
||||||
|
} else {
|
||||||
|
action = m_ui->menuTags->addAction(icons()->icon("tag"), tag);
|
||||||
|
action->setCheckable(true);
|
||||||
|
action->setChecked(selectedTags.contains(tag));
|
||||||
|
m_setTagsMenuActions->addAction(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove missing tags
|
||||||
|
for (const auto action : m_ui->menuTags->actions()) {
|
||||||
|
if (!tagList.contains(action->text())) {
|
||||||
|
action->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,6 +961,14 @@ void MainWindow::updateMenuActionState()
|
|||||||
m_ui->menuEntryCopyAttribute->setEnabled(singleEntryOrEditing);
|
m_ui->menuEntryCopyAttribute->setEnabled(singleEntryOrEditing);
|
||||||
m_ui->menuEntryTotp->setEnabled(singleEntrySelected);
|
m_ui->menuEntryTotp->setEnabled(singleEntrySelected);
|
||||||
m_ui->menuTags->setEnabled(multiEntrySelected);
|
m_ui->menuTags->setEnabled(multiEntrySelected);
|
||||||
|
// Handle tear-off tags menu
|
||||||
|
if (m_ui->menuTags->isTearOffMenuVisible()) {
|
||||||
|
if (!databaseUnlocked) {
|
||||||
|
m_ui->menuTags->hideTearOffMenu();
|
||||||
|
} else {
|
||||||
|
updateSetTagsMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
|
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
|
||||||
m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
|
m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
|
||||||
m_ui->actionEntryAutoTypeSequence->setText(singleEntrySelected
|
m_ui->actionEntryAutoTypeSequence->setText(singleEntrySelected
|
||||||
|
@ -314,6 +314,9 @@
|
|||||||
<addaction name="actionEntrySetupTotp"/>
|
<addaction name="actionEntrySetupTotp"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuTags">
|
<widget class="QMenu" name="menuTags">
|
||||||
|
<property name="tearOffEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Tags</string>
|
<string>Tags</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -2636,7 +2636,21 @@ void BaseStyle::drawControl(ControlElement element,
|
|||||||
}
|
}
|
||||||
break;
|
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: {
|
case CE_MenuItem: {
|
||||||
auto menuItem = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
|
auto menuItem = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
|
||||||
if (!menuItem)
|
if (!menuItem)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user