annotate base/RecentFiles.cpp @ 1857:14c776dad920

Make Serialiser cancellable while waiting for its lock
author Chris Cannam
date Thu, 14 May 2020 16:35:39 +0100
parents 452b48b29c2d
children
rev   line source
Chris@149 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@149 2
Chris@149 3 /*
Chris@149 4 Sonic Visualiser
Chris@149 5 An audio file viewer and annotation editor.
Chris@149 6 Centre for Digital Music, Queen Mary, University of London.
Chris@149 7 This file copyright 2006 Chris Cannam.
Chris@149 8
Chris@149 9 This program is free software; you can redistribute it and/or
Chris@149 10 modify it under the terms of the GNU General Public License as
Chris@149 11 published by the Free Software Foundation; either version 2 of the
Chris@149 12 License, or (at your option) any later version. See the file
Chris@149 13 COPYING included with this distribution for more information.
Chris@149 14 */
Chris@149 15
Chris@149 16 #include "RecentFiles.h"
Chris@149 17
Chris@277 18 #include "Preferences.h"
Chris@277 19
Chris@149 20 #include <QFileInfo>
Chris@156 21 #include <QSettings>
Chris@209 22 #include <QRegExp>
Chris@1704 23 #include <QMutexLocker>
Chris@149 24
Chris@928 25 RecentFiles::RecentFiles(QString settingsGroup, int maxCount) :
Chris@166 26 m_settingsGroup(settingsGroup),
Chris@166 27 m_maxCount(maxCount)
Chris@149 28 {
Chris@166 29 read();
Chris@149 30 }
Chris@149 31
Chris@149 32 RecentFiles::~RecentFiles()
Chris@149 33 {
Chris@149 34 // nothing
Chris@149 35 }
Chris@149 36
Chris@149 37 void
Chris@166 38 RecentFiles::read()
Chris@149 39 {
Chris@1704 40 // Private method - called only from constructor - no mutex lock required
Chris@1704 41
Chris@1704 42 m_entries.clear();
Chris@156 43 QSettings settings;
Chris@166 44 settings.beginGroup(m_settingsGroup);
Chris@156 45
Chris@928 46 for (int i = 0; i < 100; ++i) {
Chris@1704 47
Chris@1704 48 QString idKey = QString("recent-%1").arg(i);
Chris@1704 49 QString identifier = settings.value(idKey, "").toString();
Chris@1704 50 if (identifier == "") break;
Chris@1704 51
Chris@1704 52 QString labelKey = QString("recent-%1-label").arg(i);
Chris@1704 53 QString label = settings.value(labelKey, "").toString();
Chris@1704 54
Chris@1704 55 if (i < m_maxCount) m_entries.push_back({ identifier, label });
Chris@1704 56 else {
Chris@1704 57 settings.setValue(idKey, "");
Chris@1704 58 settings.setValue(labelKey, "");
Chris@1704 59 }
Chris@149 60 }
Chris@156 61
Chris@156 62 settings.endGroup();
Chris@149 63 }
Chris@149 64
Chris@149 65 void
Chris@166 66 RecentFiles::write()
Chris@149 67 {
Chris@1704 68 // Private method - must be serialised at call site
Chris@1704 69
Chris@156 70 QSettings settings;
Chris@166 71 settings.beginGroup(m_settingsGroup);
Chris@156 72
Chris@928 73 for (int i = 0; i < m_maxCount; ++i) {
Chris@1704 74 QString idKey = QString("recent-%1").arg(i);
Chris@1704 75 QString labelKey = QString("recent-%1-label").arg(i);
Chris@1704 76 QString identifier;
Chris@1704 77 QString label;
Chris@1704 78 if (in_range_for(m_entries, i)) {
Chris@1704 79 identifier = m_entries[i].first;
Chris@1704 80 label = m_entries[i].second;
Chris@1704 81 }
Chris@1704 82 settings.setValue(idKey, identifier);
Chris@1704 83 settings.setValue(labelKey, label);
Chris@149 84 }
Chris@156 85
Chris@156 86 settings.endGroup();
Chris@149 87 }
Chris@149 88
Chris@149 89 void
Chris@149 90 RecentFiles::truncateAndWrite()
Chris@149 91 {
Chris@1704 92 // Private method - must be serialised at call site
Chris@1704 93
Chris@1704 94 while (int(m_entries.size()) > m_maxCount) {
Chris@1704 95 m_entries.pop_back();
Chris@149 96 }
Chris@166 97 write();
Chris@149 98 }
Chris@149 99
Chris@149 100 std::vector<QString>
Chris@1704 101 RecentFiles::getRecentIdentifiers() const
Chris@149 102 {
Chris@1704 103 QMutexLocker locker(&m_mutex);
Chris@1704 104
Chris@1704 105 std::vector<QString> identifiers;
Chris@928 106 for (int i = 0; i < m_maxCount; ++i) {
Chris@1704 107 if (i < (int)m_entries.size()) {
Chris@1704 108 identifiers.push_back(m_entries[i].first);
Chris@149 109 }
Chris@149 110 }
Chris@1704 111
Chris@1704 112 return identifiers;
Chris@1704 113 }
Chris@1704 114
Chris@1704 115 std::vector<std::pair<QString, QString>>
Chris@1704 116 RecentFiles::getRecentEntries() const
Chris@1704 117 {
Chris@1704 118 QMutexLocker locker(&m_mutex);
Chris@1704 119
Chris@1704 120 std::vector<std::pair<QString, QString>> entries;
Chris@1704 121 for (int i = 0; i < m_maxCount; ++i) {
Chris@1704 122 if (i < (int)m_entries.size()) {
Chris@1704 123 entries.push_back(m_entries[i]);
Chris@1704 124 }
Chris@1704 125 }
Chris@1704 126
Chris@1704 127 return entries;
Chris@149 128 }
Chris@149 129
Chris@149 130 void
Chris@1704 131 RecentFiles::add(QString identifier, QString label)
Chris@149 132 {
Chris@1704 133 {
Chris@1704 134 QMutexLocker locker(&m_mutex);
Chris@1704 135
Chris@1704 136 bool have = false;
Chris@1704 137 for (int i = 0; i < int(m_entries.size()); ++i) {
Chris@1704 138 if (m_entries[i].first == identifier) {
Chris@1704 139 have = true;
Chris@1704 140 break;
Chris@1704 141 }
Chris@149 142 }
Chris@1704 143
Chris@1704 144 if (!have) {
Chris@1704 145 m_entries.push_front({ identifier, label });
Chris@1704 146 } else {
Chris@1704 147 std::deque<std::pair<QString, QString>> newEntries;
Chris@1704 148 newEntries.push_back({ identifier, label });
Chris@1704 149 for (int i = 0; in_range_for(m_entries, i); ++i) {
Chris@1704 150 if (m_entries[i].first == identifier) continue;
Chris@1704 151 newEntries.push_back(m_entries[i]);
Chris@1704 152 }
Chris@1704 153 m_entries = newEntries;
Chris@1704 154 }
Chris@1704 155
Chris@1704 156 truncateAndWrite();
Chris@149 157 }
Chris@149 158
Chris@166 159 emit recentChanged();
Chris@149 160 }
Chris@149 161
Chris@166 162 void
Chris@1704 163 RecentFiles::addFile(QString filepath, QString label)
Chris@166 164 {
Chris@209 165 static QRegExp schemeRE("^[a-zA-Z]{2,5}://");
Chris@277 166 static QRegExp tempRE("[\\/][Tt]e?mp[\\/]");
Chris@1704 167 if (schemeRE.indexIn(filepath) == 0) {
Chris@1704 168 add(filepath, label);
Chris@209 169 } else {
Chris@1704 170 QString absPath = QFileInfo(filepath).absoluteFilePath();
Chris@277 171 if (tempRE.indexIn(absPath) != -1) {
Chris@277 172 Preferences *prefs = Preferences::getInstance();
Chris@277 173 if (prefs && !prefs->getOmitTempsFromRecentFiles()) {
Chris@1704 174 add(absPath, label);
Chris@277 175 }
Chris@277 176 } else {
Chris@1704 177 add(absPath, label);
Chris@277 178 }
Chris@209 179 }
Chris@166 180 }
Chris@149 181
Chris@166 182