File indexing completed on 2024-05-05 04:50:49
0001 /* 0002 * SPDX-FileCopyrightText: 2021 George Florea Bănuș <georgefb899@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "recentfilesmodel.h" 0008 0009 #include <KSharedConfig> 0010 0011 #include <QJsonDocument> 0012 #include <QMenu> 0013 #include <QProcess> 0014 0015 #include "application.h" 0016 #include "generalsettings.h" 0017 #include "global.h" 0018 0019 RecentFilesModel::RecentFilesModel(QObject *parent) 0020 : QAbstractListModel(parent) 0021 { 0022 auto config = KSharedConfig::openConfig(Global::instance()->appConfigFilePath(Global::ConfigFile::RecentFiles)); 0023 m_recentFilesConfigGroup = config->group(QStringLiteral("RecentFiles")); 0024 setMaxRecentFiles(GeneralSettings::maxRecentFiles()); 0025 populate(); 0026 } 0027 0028 int RecentFilesModel::rowCount(const QModelIndex &parent) const 0029 { 0030 if (parent.isValid()) { 0031 return 0; 0032 } 0033 0034 return m_urls.count(); 0035 } 0036 0037 QVariant RecentFilesModel::data(const QModelIndex &index, int role) const 0038 { 0039 if (!index.isValid()) { 0040 return QVariant(); 0041 } 0042 0043 RecentFile recentFile = m_urls.at(index.row()); 0044 0045 switch (role) { 0046 case PathRole: 0047 return QVariant(recentFile.url); 0048 case NameRole: 0049 return QVariant(recentFile.name); 0050 } 0051 0052 return QVariant(); 0053 } 0054 0055 QHash<int, QByteArray> RecentFilesModel::roleNames() const 0056 { 0057 QHash<int, QByteArray> roles; 0058 roles[PathRole] = "path"; 0059 roles[NameRole] = "name"; 0060 0061 return roles; 0062 } 0063 0064 void RecentFilesModel::populate() 0065 { 0066 if (GeneralSettings::maxRecentFiles() <= 0) { 0067 deleteEntries(); 0068 return; 0069 } 0070 0071 clear(); 0072 setMaxRecentFiles(GeneralSettings::maxRecentFiles()); 0073 0074 for (int i = 0; i < maxRecentFiles(); i++) { 0075 auto file = m_recentFilesConfigGroup.readPathEntry(QStringLiteral("File%1").arg(i + 1), QString()); 0076 auto name = m_recentFilesConfigGroup.readPathEntry(QStringLiteral("Name%1").arg(i + 1), QString()); 0077 if (file.isEmpty()) { 0078 break; 0079 } 0080 QUrl url(file); 0081 if (!url.isLocalFile() && url.scheme().isEmpty()) { 0082 url.setScheme(QStringLiteral("file")); 0083 } 0084 RecentFile recentFile; 0085 recentFile.url = url; 0086 recentFile.name = name; 0087 0088 beginInsertRows(QModelIndex(), i, i); 0089 m_urls.append(recentFile); 0090 endInsertRows(); 0091 } 0092 } 0093 0094 void RecentFilesModel::addUrl(const QString &path, const QString &name) 0095 { 0096 if (maxRecentFiles() == 0) { 0097 return; 0098 } 0099 0100 auto url = QUrl::fromUserInput(path); 0101 if (!url.isValid()) { 0102 return; 0103 } 0104 0105 if (url.scheme().startsWith(QStringLiteral("http")) && name.isEmpty()) { 0106 getHttpItemInfo(url); 0107 } 0108 0109 auto _name = name == QString() ? url.fileName() : name; 0110 0111 for (int i{0}; i < m_urls.count(); ++i) { 0112 if (url == m_urls[i].url) { 0113 beginRemoveRows(QModelIndex(), i, i); 0114 m_urls.takeAt(i); 0115 endRemoveRows(); 0116 break; 0117 } 0118 } 0119 0120 RecentFile recentFile; 0121 recentFile.url = url; 0122 recentFile.name = _name; 0123 0124 if (m_urls.count() == maxRecentFiles()) { 0125 beginRemoveRows(QModelIndex(), m_urls.count() - 1, m_urls.count() - 1); 0126 m_urls.removeLast(); 0127 endRemoveRows(); 0128 } 0129 0130 beginInsertRows(QModelIndex(), 0, 0); 0131 m_urls.prepend(recentFile); 0132 endInsertRows(); 0133 0134 saveEntries(); 0135 } 0136 0137 void RecentFilesModel::clear() 0138 { 0139 beginResetModel(); 0140 m_urls.clear(); 0141 endResetModel(); 0142 } 0143 0144 void RecentFilesModel::deleteEntries() 0145 { 0146 clear(); 0147 m_recentFilesConfigGroup.deleteGroup(); 0148 m_recentFilesConfigGroup.sync(); 0149 } 0150 0151 void RecentFilesModel::saveEntries() 0152 { 0153 m_recentFilesConfigGroup.deleteGroup(); 0154 int i = 1; 0155 for (const auto &[url, name] : std::as_const(m_urls)) { 0156 m_recentFilesConfigGroup.writePathEntry(QStringLiteral("File%1").arg(i), url.toDisplayString(QUrl::PreferLocalFile)); 0157 m_recentFilesConfigGroup.writePathEntry(QStringLiteral("Name%1").arg(i), name); 0158 0159 ++i; 0160 } 0161 m_recentFilesConfigGroup.sync(); 0162 } 0163 0164 int RecentFilesModel::maxRecentFiles() const 0165 { 0166 return m_maxRecentFiles; 0167 } 0168 0169 void RecentFilesModel::setMaxRecentFiles(int _maxRecentFiles) 0170 { 0171 m_maxRecentFiles = _maxRecentFiles; 0172 } 0173 0174 void RecentFilesModel::getHttpItemInfo(const QUrl &url) 0175 { 0176 auto ytdlProcess = new QProcess(); 0177 ytdlProcess->setProgram(Application::youtubeDlExecutable()); 0178 ytdlProcess->setArguments(QStringList() << QStringLiteral("-j") << url.toString()); 0179 ytdlProcess->start(); 0180 0181 connect(ytdlProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { 0182 QString json = QString::fromUtf8(ytdlProcess->readAllStandardOutput()); 0183 QString title = QJsonDocument::fromJson(json.toUtf8())[QStringLiteral("title")].toString(); 0184 if (title.isEmpty()) { 0185 return; 0186 } 0187 0188 addUrl(url.toString(), title); 0189 }); 0190 } 0191 0192 #include "moc_recentfilesmodel.cpp"