File indexing completed on 2024-05-05 17:04:26

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2012 Boudewijn Rempt <boud@kogmbh.com>
0003  *
0004  *  This program is free software; you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation; either version 2 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program; if not, write to the Free Software
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0017  */
0018 #include "RecentFileManager.h"
0019 
0020 #include <QFile>
0021 #include <QFileInfo>
0022 #include <QDir>
0023 #include <QUrl>
0024 #include <QDebug>
0025 
0026 #include <KSharedConfig>
0027 #include <kconfiggroup.h>
0028 #include <kconfig.h>
0029 
0030 
0031 // Much of this is a gui-less clone of KRecentFilesAction, so the format of
0032 // storing recent files is compatible.
0033 struct RecentFileEntry {
0034     QString fileName;
0035     QString filePath;
0036 };
0037 
0038 class RecentFileManager::Private {
0039 public:
0040     Private()
0041     {
0042         KConfigGroup grp(KSharedConfig::openConfig(), "RecentFiles");
0043         maxItems = grp.readEntry("maxRecentFileItems", 100);
0044 
0045         loadEntries(grp);
0046     }
0047 
0048     void loadEntries(const KConfigGroup &grp)
0049     {
0050         recents.clear();
0051 
0052         QString value;
0053         QString nameValue;
0054         QUrl url;
0055 
0056         KConfigGroup cg = grp;
0057 
0058         if ( cg.name().isEmpty()) {
0059             cg = KConfigGroup(cg.config(),"RecentFiles");
0060         }
0061 
0062         // read file list
0063         for (int i = 1; i <= maxItems; i++) {
0064 
0065             value = cg.readPathEntry(QString("File%1").arg(i), QString());
0066             if (value.isEmpty()) continue;
0067             url = QUrl(value);
0068 
0069             // gemini only handles local files
0070             // yes, i know the second half here isn't good on windows... but without it we fail on linux, and second part for windows
0071             if (!url.isLocalFile() && !value.startsWith('/') && value.midRef(2, 1) != QLatin1String(":")) {
0072                 qDebug() << "Not a local file:" << url;
0073                 continue;
0074             }
0075 
0076             // Don't restore if file doesn't exist anymore
0077             if (!QFile::exists(url.toLocalFile()) && !QFile::exists(value)) {
0078                 qDebug() << "Recent file apparently no longer exists:" << url.toLocalFile();
0079                 continue;
0080             }
0081 
0082             value = QDir::toNativeSeparators( value );
0083 
0084             // Don't restore where the url is already known (eg. broken config)
0085             for (const RecentFileEntry& entry : recents) {
0086                 if (entry.filePath == value) {
0087                     continue;
0088                 }
0089             }
0090 
0091             nameValue = cg.readPathEntry(QString("Name%1").arg(i), url.fileName());
0092 
0093             if (!value.isNull())  {
0094                 RecentFileEntry entry;
0095                 entry.fileName = nameValue;
0096                 entry.filePath = value;
0097                 recents << entry;
0098            }
0099         }
0100     }
0101 
0102     void saveEntries( const KConfigGroup &grp)
0103     {
0104         KConfigGroup cg = grp;
0105 
0106         if (cg.name().isEmpty()) {
0107             cg = KConfigGroup(cg.config(),"RecentFiles");
0108         }
0109         cg.deleteGroup();
0110 
0111         // write file list
0112         for (int i = 1; i <= recents.size(); ++i) {
0113             // i - 1 because we started from 1
0114             const RecentFileEntry &item = recents[i-1];
0115             cg.writePathEntry(QString("File%1").arg(i), item.filePath);
0116             cg.writePathEntry(QString("Name%1").arg(i), item.fileName);
0117         }
0118     }
0119 
0120     int maxItems;
0121     QList<RecentFileEntry> recents;
0122 };
0123 
0124 
0125 
0126 
0127 RecentFileManager::RecentFileManager(QObject *parent)
0128     : QObject(parent)
0129     , d(new Private())
0130 {
0131 }
0132 
0133 RecentFileManager::~RecentFileManager()
0134 {
0135     KConfigGroup grp(KSharedConfig::openConfig(), "RecentFiles");
0136     grp.writeEntry("maxRecentFileItems", d->maxItems);
0137     delete d;
0138 }
0139 
0140 
0141 QStringList RecentFileManager::recentFileNames() const
0142 {
0143     QStringList files;
0144     for(const RecentFileEntry &item : d->recents) {
0145         files << item.fileName;
0146     }
0147     return files;
0148 }
0149 
0150 QStringList RecentFileManager::recentFiles() const
0151 {
0152     QStringList files;
0153     for(const RecentFileEntry &item : d->recents) {
0154         files << item.filePath;
0155     }
0156     return files;
0157 }
0158 
0159 void RecentFileManager::addRecent(const QString &_url)
0160 {
0161     if (d->recents.size() > d->maxItems) {
0162         d->recents.removeLast();
0163     }
0164 
0165     RecentFileEntry newEntry;
0166     newEntry.filePath = QDir::toNativeSeparators(_url);
0167     newEntry.fileName  = QFileInfo(_url).fileName();
0168 
0169     QMutableListIterator<RecentFileEntry> i(d->recents);
0170     while (i.hasNext()) {
0171         i.next();
0172         if (i.value().filePath == newEntry.filePath) {
0173             i.remove();
0174         }
0175     }
0176     d->recents.insert(0, newEntry);
0177 
0178     d->saveEntries(KConfigGroup(KSharedConfig::openConfig(), "RecentFiles"));
0179     emit recentFilesListChanged();
0180 }
0181 
0182 int RecentFileManager::size()
0183 {
0184     return d->recents.size();
0185 }
0186 
0187 QString RecentFileManager::recentFile(int index) const
0188 {
0189     if (index < d->recents.size()) {
0190         return d->recents.at(index).filePath;
0191     }
0192     return QString();
0193 }
0194 
0195 QString RecentFileManager::recentFileName(int index) const
0196 {
0197     if (index < d->recents.size()) {
0198         return d->recents.at(index).fileName;
0199     }
0200     return QString();
0201 }