File indexing completed on 2024-05-12 17:07:25

0001 /*
0002     SPDX-FileCopyrightText: 2009 Ben Cooksley <ben@eclipse.endoftheinternet.org>
0003     SPDX-FileCopyrightText: 2007 Will Stephenson <wstephenson@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "ActionModel.h"
0009 #include "ActionItem.h"
0010 
0011 #include <KDesktopFileActions>
0012 #include <KService>
0013 
0014 #include <QDirIterator>
0015 #include <QIcon>
0016 #include <QStandardPaths>
0017 
0018 class ActionModel::Private
0019 {
0020 public:
0021     Private()
0022     {
0023     }
0024 
0025     QList<ActionItem *> actions;
0026 };
0027 
0028 static bool sortAction(ActionItem *left, ActionItem *right)
0029 {
0030     return left->name().localeAwareCompare(right->name()) < 0;
0031 }
0032 
0033 ActionModel::ActionModel(QObject *parent)
0034     : QAbstractTableModel(parent)
0035     , d(new Private())
0036 {
0037 }
0038 
0039 ActionModel::~ActionModel()
0040 {
0041     qDeleteAll(d->actions);
0042     d->actions.clear();
0043     delete d;
0044 }
0045 
0046 int ActionModel::columnCount(const QModelIndex &parent) const
0047 {
0048     Q_UNUSED(parent);
0049     return 2;
0050 }
0051 
0052 int ActionModel::rowCount(const QModelIndex &parent) const
0053 {
0054     if (!parent.isValid()) {
0055         return d->actions.count();
0056     }
0057     return 0;
0058 }
0059 
0060 QVariant ActionModel::data(const QModelIndex &index, int role) const
0061 {
0062     QVariant theData;
0063     if (!index.isValid()) {
0064         return QVariant();
0065     }
0066 
0067     ActionItem *mi = d->actions.at(index.row());
0068     switch (role) {
0069     case Qt::DisplayRole:
0070         if (index.column() == 0) {
0071             theData.setValue(mi->name());
0072         } else if (index.column() == 1) {
0073             theData.setValue(mi->involvedTypes());
0074         }
0075         break;
0076     case Qt::DecorationRole:
0077         if (index.column() == 0) {
0078             theData = QIcon::fromTheme(mi->icon());
0079         }
0080         break;
0081     case Qt::UserRole:
0082         theData.setValue(mi);
0083         break;
0084     default:
0085         break;
0086     }
0087     return theData;
0088 }
0089 
0090 void ActionModel::buildActionList()
0091 {
0092     beginResetModel();
0093     qDeleteAll(d->actions);
0094     d->actions.clear();
0095     // Prepare to search for possible actions -> we only want solid types
0096     const QStringList actionDirs =
0097         QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("solid/actions"), QStandardPaths::LocateDirectory);
0098     // Get service objects for those actions and add them to the display
0099     for (const QString &actionDir : actionDirs) {
0100         QDirIterator it(actionDir, QStringList() << QStringLiteral("*.desktop"));
0101         while (it.hasNext()) {
0102             it.next();
0103             const QString desktop = it.filePath();
0104             const KService::Ptr desktopService = KService::serviceByStorageId(it.filePath());
0105             // Get contained services list
0106             const QList<KServiceAction> services = KDesktopFileActions::userDefinedServices(*desktopService, true);
0107             for (const KServiceAction &deviceAction : services) {
0108                 ActionItem *actionItem = new ActionItem(desktop, deviceAction.name(), this); // Create an action
0109                 d->actions.append(actionItem);
0110             }
0111         }
0112     }
0113 
0114     std::sort(d->actions.begin(), d->actions.end(), sortAction);
0115     endResetModel();
0116 }
0117 
0118 QList<ActionItem *> ActionModel::actionList() const
0119 {
0120     return d->actions;
0121 }