qtdoc/examples/demos/documentviewer/app/recentfiles.cpp

129 lines
3.2 KiB
C++

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "recentfiles.h"
#include <QFileInfo>
#include <QSettings>
// Test if file exists and can be opened
static bool testFileAccess(const QString &fileName)
{
return QFileInfo(fileName).isReadable();
}
void RecentFiles::clear()
{
if (isEmpty())
return;
m_files.clear();
emit countChanged(0);
}
void RecentFiles::addFile(const QString &fileName, EmitPolicy policy)
{
if (!testFileAccess(fileName))
return;
// Remember size, as cleanup can result in a change without size change
const qsizetype c = m_files.count();
// Clean dangling and duplicate files
for (qsizetype i = 0; i < m_files.size(); ) {
const QString &file = m_files.at(i);
if (!testFileAccess(file)) {
removeFile(file, RemoveReason::Other);
} else if (file == fileName) {
removeFile(file, RemoveReason::Duplicate);
} else {
++i;
}
}
// Cut tail
while (m_files.count() > m_maxFiles)
removeFile((m_files.count() - 1), RemoveReason::Other);
m_files.prepend(fileName);
switch (policy) {
case EmitPolicy::NeverEmit:
return;
case EmitPolicy::EmitWhenChanged:
emit changed();
if (c != m_files.count())
emit countChanged(m_files.count());
return;
}
}
void RecentFiles::addFiles(const QStringList &files)
{
if (files.isEmpty())
return;
if (files.count() == 1) {
addFile(files.at(0));
return;
}
const qsizetype c = m_files.count();
for (const auto &file : files)
addFile(file, EmitPolicy::NeverEmit);
emit changed();
if (m_files.count() != c)
emit countChanged(m_files.count());
}
void RecentFiles::removeFile(qsizetype index, RemoveReason reason)
{
if (index < 0 || index >= m_files.count())
return;
m_files.remove(index);
// No emit for duplicate removal, add emits changed later.
if (reason != RemoveReason::Duplicate)
emit changed();
}
void RecentFiles::saveSettings(QSettings &settings, const QString &key) const
{
settings.beginGroup(key);
settings.setValue(s_maxFiles, maxFiles());
if (!isEmpty()) {
settings.beginWriteArray(s_fileNames, m_files.count());
for (int index = 0; index < m_files.count(); ++index) {
settings.setArrayIndex(index);
settings.setValue(s_file, m_files.at(index));
}
settings.endArray();
}
settings.endGroup();
}
bool RecentFiles::restoreFromSettings(QSettings &settings, const QString &key)
{
settings.beginGroup(key);
const qsizetype mxFiles = settings.value(s_maxFiles, maxFiles()).toLongLong();
setMaxFiles(mxFiles);
m_files.clear(); // clear list without emitting
const int numberFiles = settings.beginReadArray(s_fileNames);
for (int index = 0; index < numberFiles; ++index) {
settings.setArrayIndex(index);
const QString absoluteFilePath = settings.value(s_file).toString();
addFile(absoluteFilePath, EmitPolicy::NeverEmit);
}
settings.endArray();
settings.endGroup();
if (!m_files.isEmpty())
emit changed();
return true;
}