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