File indexing completed on 2024-06-16 04:40:27
0001 /* 0002 * SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "FileItemLinkingPluginActionLoader.h" 0008 0009 #include <KFileItemListProperties> 0010 #include <utils/d_ptr_implementation.h> 0011 #include <utils/qsqlquery_iterator.h> 0012 0013 #include <QCursor> 0014 #include <QDBusPendingCall> 0015 #include <QDebug> 0016 #include <QFileInfo> 0017 #include <QMenu> 0018 #include <QSqlDatabase> 0019 #include <QSqlDriver> 0020 #include <QSqlError> 0021 #include <QSqlField> 0022 #include <QSqlQuery> 0023 #include <QStandardPaths> 0024 0025 #include <KLocalizedString> 0026 #include <KPluginFactory> 0027 0028 #include "common/dbus/common.h" 0029 0030 FileItemLinkingPluginActionLoader *FileItemLinkingPluginActionLoader::create(const KFileItemListProperties &items) 0031 { 0032 auto l = new FileItemLinkingPluginActionLoader(items); 0033 connect(l, &QThread::finished, l, &QObject::deleteLater); 0034 return l; 0035 } 0036 0037 FileItemLinkingPluginActionLoader::FileItemLinkingPluginActionLoader(const KFileItemListProperties &items) 0038 : items(items) 0039 { 0040 } 0041 0042 void FileItemLinkingPluginActionLoader::run() 0043 { 0044 ActionList actions; 0045 0046 const auto activitiesList = activities.activities(); 0047 const auto itemsSize = items.urlList().size(); 0048 0049 if (itemsSize >= 10) { 0050 // we are not going to check for this large number of files 0051 actions << createAction(QString(), true, i18n("Link to the current activity"), "list-add"); 0052 actions << createAction(QString(), false, i18n("Unlink from the current activity"), "list-remove"); 0053 0054 actions << createSeparator(i18n("Link to:")); 0055 for (const auto &activity : activitiesList) { 0056 actions << createAction(activity, true); 0057 } 0058 0059 actions << createSeparator(i18n("Unlink from:")); 0060 for (const auto &activity : activitiesList) { 0061 actions << createAction(activity, false); 0062 } 0063 0064 } else { 0065 const QString connectionName = QStringLiteral("kactivities_db_resources_") + QString::number((quintptr)this); 0066 0067 { 0068 auto database = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connectionName); 0069 0070 database.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) 0071 + QStringLiteral("/kactivitymanagerd/resources/database")); 0072 0073 if (database.open()) { 0074 static const auto queryString = QStringLiteral( 0075 "SELECT usedActivity, COUNT(targettedResource) " 0076 "FROM ResourceLink " 0077 "WHERE targettedResource IN (%1) " 0078 "AND initiatingAgent = \":global\" " 0079 "AND usedActivity != \":global\" " 0080 "GROUP BY usedActivity"); 0081 0082 QStringList escapedFiles; 0083 QSqlField field; 0084 field.setType(QVariant::String); 0085 0086 const auto urlList = items.urlList(); 0087 for (const auto &item : urlList) { 0088 field.setValue(QFileInfo(item.toLocalFile()).canonicalFilePath()); 0089 escapedFiles << database.driver()->formatValue(field); 0090 } 0091 0092 QSqlQuery query(queryString.arg(escapedFiles.join(",")), database); 0093 0094 QStringList activitiesForLinking; 0095 QStringList activitiesForUnlinking; 0096 0097 for (const auto &result : query) { 0098 const auto linkedFileCount = result[1].toInt(); 0099 const auto activity = result[0].toString(); 0100 if (linkedFileCount < itemsSize) { 0101 activitiesForLinking << activity; 0102 } 0103 0104 if (linkedFileCount > 0) { 0105 activitiesForUnlinking << activity; 0106 } 0107 } 0108 0109 if (activitiesForLinking.contains(activities.currentActivity()) || !activitiesForUnlinking.contains(activities.currentActivity())) { 0110 actions << createAction(QString(), true, i18n("Link to the current activity"), "list-add"); 0111 } 0112 if (activitiesForUnlinking.contains(activities.currentActivity())) { 0113 actions << createAction(QString(), false, i18n("Unlink from the current activity"), "list-remove"); 0114 } 0115 0116 actions << createSeparator(i18n("Link to:")); 0117 for (const auto &activity : activitiesList) { 0118 if (activitiesForLinking.contains(activity) || !activitiesForUnlinking.contains(activity)) { 0119 actions << createAction(activity, true); 0120 } 0121 } 0122 0123 actions << createSeparator(i18n("Unlink from:")); 0124 for (const auto &activity : activitiesList) { 0125 if (activitiesForUnlinking.contains(activity)) { 0126 actions << createAction(activity, false); 0127 } 0128 } 0129 0130 database.close(); 0131 } 0132 } 0133 0134 QSqlDatabase::removeDatabase(connectionName); 0135 } 0136 0137 Q_EMIT result(actions); 0138 } 0139 0140 Action FileItemLinkingPluginActionLoader::createAction(const QString &activity, bool link, const QString &title, const QString &icon) const 0141 { 0142 Action action = {}; 0143 action.link = link; 0144 0145 if (title.isEmpty()) { 0146 KActivities::Info activityInfo(activity); 0147 action.title = activityInfo.name(); 0148 action.icon = activityInfo.icon().isEmpty() ? "activities" : activityInfo.icon(); 0149 0150 } else { 0151 action.title = title; 0152 } 0153 0154 if (!icon.isEmpty()) { 0155 action.icon = icon; 0156 } 0157 0158 action.activity = activity.isEmpty() ? activities.currentActivity() : activity; 0159 0160 return action; 0161 } 0162 0163 Action FileItemLinkingPluginActionLoader::createSeparator(const QString &title) const 0164 { 0165 Action action = {}; 0166 action.icon = "-"; 0167 action.title = title; 0168 return action; 0169 } 0170 0171 #include "moc_FileItemLinkingPluginActionLoader.cpp"