Qt Utilities 6.23.0
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
Loading...
Searching...
No Matches
recentmenumanager.cpp
Go to the documentation of this file.
2
3#include <QAction>
4#include <QCoreApplication>
5#include <QFile>
6#include <QMenu>
7#include <QMessageBox>
8#include <QPushButton>
9#include <QStringList>
10
11namespace QtUtilities {
12
18
30RecentMenuManager::RecentMenuManager(QMenu *menu, QObject *parent)
31 : QObject(parent)
32 , m_menu(menu)
33{
34 m_menu->clear();
35 m_menu->setTitle(tr("&Recent"));
36 m_menu->setIcon(QIcon::fromTheme(QStringLiteral("document-open-recent-symbolic")));
37 m_sep = m_menu->addSeparator();
38 m_clearAction
39 = m_menu->addAction(QIcon::fromTheme(QStringLiteral("edit-clear-symbolic")), tr("&Clear list"), this, &RecentMenuManager::clearEntries);
40}
41
45void RecentMenuManager::restore(const QStringList &savedEntries)
46{
47 QAction *action = nullptr;
48 for (const QString &path : savedEntries) {
49 if (!path.isEmpty()) {
50 action = new QAction(path, m_menu);
51 action->setProperty("file_path", path);
52 m_menu->insertAction(m_sep, action);
53 connect(action, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered);
54 }
55 }
56 if (action) {
57 m_menu->actions().front()->setShortcut(QKeySequence(Qt::Key_F6));
58 m_menu->setEnabled(true);
59 }
60}
61
66{
67 QStringList existingEntires;
68 QList<QAction *> entryActions = m_menu->actions();
69 existingEntires.reserve(entryActions.size());
70 for (const QAction *action : entryActions) {
71 QVariant path = action->property("file_path");
72 if (!path.isNull()) {
73 existingEntires << path.toString();
74 }
75 }
76 return existingEntires;
77}
78
83void RecentMenuManager::addEntry(const QString &path)
84{
85 QList<QAction *> existingEntries = m_menu->actions();
86 QAction *entry = nullptr;
87 // remove shortcut from existing entries
88 for (QAction *existingEntry : existingEntries) {
89 existingEntry->setShortcut(QKeySequence());
90 // check whether existing entry matches entry to add
91 if (existingEntry->property("file_path").toString() == path) {
92 entry = existingEntry;
93 break;
94 }
95 }
96 if (!entry) {
97 // remove old entries to have never more than 10 entries
98 for (auto i = existingEntries.size() - 1; i > 8; --i) {
99 delete existingEntries[i];
100 }
101 existingEntries = m_menu->actions();
102 // create new action
103 entry = new QAction(path, this);
104 entry->setProperty("file_path", path);
105 connect(entry, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered);
106 } else {
107 // remove existing action (will be inserted again as first action)
108 m_menu->removeAction(entry);
109 }
110 // add shortcut for new entry
111 entry->setShortcut(QKeySequence(Qt::Key_F6));
112 // ensure menu is enabled
113 m_menu->setEnabled(true);
114 // add action as first action in the recent menu
115 m_menu->insertAction(m_menu->isEmpty() ? nullptr : m_menu->actions().front(), entry);
116}
117
122{
123 QList<QAction *> entries = m_menu->actions();
124 for (auto i = entries.begin(), end = entries.end() - 2; i != end; ++i) {
125 if (*i != m_clearAction) {
126 delete *i;
127 }
128 }
129 m_menu->setEnabled(false);
130}
131
136void RecentMenuManager::handleActionTriggered()
137{
138 if (QAction *action = qobject_cast<QAction *>(sender())) {
139 const QString path = action->property("file_path").toString();
140 if (!path.isEmpty()) {
141 if (QFile::exists(path)) {
142 emit fileSelected(path);
143 } else {
144 QMessageBox msg;
145 msg.setWindowTitle(tr("Recently opened files - ") + QCoreApplication::applicationName());
146 msg.setText(tr("The selected file can't be found anymore. Do you want "
147 "to delete the obsolete entry from the list?"));
148 msg.setIcon(QMessageBox::Warning);
149 QPushButton *keepEntryButton = msg.addButton(tr("keep entry"), QMessageBox::NoRole);
150 QPushButton *deleteEntryButton = msg.addButton(tr("delete entry"), QMessageBox::YesRole);
151 msg.setEscapeButton(keepEntryButton);
152 msg.exec();
153 if (msg.clickedButton() == deleteEntryButton) {
154 delete action;
155 QList<QAction *> remainingActions = m_menu->actions();
156 if (!remainingActions.isEmpty() && remainingActions.front() != m_sep && remainingActions.front() != m_clearAction) {
157 remainingActions.front()->setShortcut(QKeySequence(Qt::Key_F6));
158 m_menu->setEnabled(true);
159 } else {
160 m_menu->setEnabled(false);
161 }
162 }
163 }
164 }
165 }
166}
167
174} // namespace QtUtilities
void addEntry(const QString &path)
Ensures an entry for the specified path is present and the first entry in the list.
void fileSelected(const QString &path)
Emitted after the user selected a file.
QStringList save()
Saves the current entries.
void restore(const QStringList &savedEntries)
Restores the specified entries.
RecentMenuManager(QMenu *menu, QObject *parent=nullptr)
Constructs a new recent menu manager.
void clearEntries()
Clears all entries.