File indexing completed on 2024-05-19 04:29:53

0001 /*
0002  * SPDX-FileCopyrightText: 2022 Alvin Wong <alvin@alvinhc.com>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "KisRecentFilesManager.h"
0008 
0009 #include <QApplication>
0010 #include <QDir>
0011 #include <QFileInfo>
0012 #include <QThread>
0013 #include <QTimer>
0014 #include <QDebug>
0015 
0016 #include <kconfig.h>
0017 #include <kconfiggroup.h>
0018 #include <ksharedconfig.h>
0019 #include <KisMpl.h>
0020 
0021 class KisRecentFilesManager::Private
0022 {
0023 public:
0024     KisRecentFilesManager *m_q;
0025     int m_maxItems {10};
0026     QVector<KisRecentFilesEntry> m_entries;
0027 
0028 private:
0029     QTimer m_saveOnIdleTimer;
0030 
0031 public:
0032     Private(KisRecentFilesManager *q);
0033 
0034     bool containsUrl(const QUrl &url) const;
0035     int indexOfUrl(const QUrl &url) const;
0036 
0037     void requestSaveOnNextTick();
0038 }; /* class KisRecentFilesEntry::Private */
0039 
0040 KisRecentFilesManager::Private::Private(KisRecentFilesManager *q)
0041     : m_q(q)
0042     , m_saveOnIdleTimer(q)
0043 {
0044     m_saveOnIdleTimer.setSingleShot(true);
0045     m_saveOnIdleTimer.setInterval(0);
0046     m_q->connect(&m_saveOnIdleTimer, &QTimer::timeout, [this]() {
0047         m_q->saveEntries(KSharedConfig::openConfig()->group("RecentFiles"));
0048     });
0049 }
0050 
0051 bool KisRecentFilesManager::Private::containsUrl(const QUrl &url) const
0052 {
0053     return indexOfUrl(url) >= 0;
0054 }
0055 
0056 int KisRecentFilesManager::Private::indexOfUrl(const QUrl &url) const
0057 {
0058     auto found = std::find_if(m_entries.constBegin(), m_entries.constEnd(),
0059                               kismpl::mem_equal_to(&KisRecentFilesEntry::m_url, url));
0060     if (found == m_entries.constEnd()) {
0061         return -1;
0062     } else {
0063         return found - m_entries.constBegin();
0064     }
0065 }
0066 
0067 void KisRecentFilesManager::Private::requestSaveOnNextTick()
0068 {
0069     // If multiple saves are requested within the same tick, they will be
0070     // consolidated by the timer.
0071     m_saveOnIdleTimer.start();
0072 }
0073 
0074 
0075 KisRecentFilesManager::KisRecentFilesManager()
0076     : m_d(new Private(this))
0077 {
0078     loadEntries(KSharedConfig::openConfig()->group("RecentFiles"));
0079 }
0080 
0081 KisRecentFilesManager::~KisRecentFilesManager()
0082 {
0083     delete m_d;
0084 }
0085 
0086 KisRecentFilesManager *KisRecentFilesManager::instance()
0087 {
0088     if (QThread::currentThread() != qApp->thread()) {
0089         qWarning() << "KisRecentFilesManager::instance() called from non-GUI thread!";
0090         return nullptr;
0091     }
0092     static KisRecentFilesManager s_instance;
0093     return &s_instance;
0094 }
0095 
0096 void KisRecentFilesManager::clear()
0097 {
0098     m_d->m_entries.clear();
0099     emit listRenewed();
0100     m_d->requestSaveOnNextTick();
0101 }
0102 
0103 void KisRecentFilesManager::remove(const QUrl &url)
0104 {
0105     int removeIndex = m_d->indexOfUrl(url);
0106     if (removeIndex >= 0) {
0107         m_d->m_entries.removeAt(removeIndex);
0108         emit fileRemoved(url);
0109         m_d->requestSaveOnNextTick();
0110     }
0111 }
0112 
0113 QVector<KisRecentFilesEntry> KisRecentFilesManager::recentFiles() const
0114 {
0115     return m_d->m_entries;
0116 }
0117 
0118 QList<QUrl> KisRecentFilesManager::recentUrlsLatestFirst() const
0119 {
0120     // switch order so last opened file is first
0121     QList<QUrl> sortedList;
0122     for (int i = m_d->m_entries.length() - 1; i >= 0; i--) {
0123         sortedList.append(m_d->m_entries[i].m_url);
0124     }
0125 
0126     return sortedList;
0127 }
0128 
0129 // The following file contains code copied and modified from LGPL-2.0-only
0130 // source:
0131 #include "KisRecentFilesManager_p.h"