File indexing completed on 2024-05-12 05:35:50

0001 /*
0002     SPDX-FileCopyrightText: 2009 Ben Cooksley <ben@eclipse.endoftheinternet.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "SolidActionData.h"
0008 
0009 #include <QDirIterator>
0010 #include <QList>
0011 #include <QMetaProperty>
0012 #include <QRegularExpression>
0013 
0014 #include <KConfigGroup>
0015 #include <KDesktopFile>
0016 #include <KFileUtils>
0017 #include <KStringHandler>
0018 
0019 #include <Solid/Battery>
0020 #include <Solid/Block>
0021 #include <Solid/Camera>
0022 #include <Solid/GenericInterface>
0023 #include <Solid/OpticalDisc>
0024 #include <Solid/OpticalDrive>
0025 #include <Solid/PortableMediaPlayer>
0026 #include <Solid/Processor>
0027 #include <Solid/StorageAccess>
0028 #include <Solid/StorageDrive>
0029 #include <Solid/StorageVolume>
0030 
0031 static SolidActionData *actData = nullptr;
0032 
0033 SolidActionData::SolidActionData(bool includeFiles)
0034 {
0035     const int propertyOffset = Solid::DeviceInterface::staticMetaObject.propertyOffset();
0036 
0037     const QList<QMetaObject> interfaceList = fillInterfaceList();
0038     for (const QMetaObject &interface : interfaceList) {
0039         QString ifaceName = interface.className();
0040         ifaceName.remove(0, ifaceName.lastIndexOf(':') + 1);
0041         Solid::DeviceInterface::Type ifaceDev = Solid::DeviceInterface::stringToType(ifaceName);
0042         const QString cleanName = Solid::DeviceInterface::typeDescription(ifaceDev);
0043         types.insert(ifaceDev, cleanName);
0044 
0045         QMap<QString, QString> deviceValues;
0046         for (int doneProps = propertyOffset; interface.propertyCount() > doneProps; doneProps = doneProps + 1) {
0047             QMetaProperty ifaceProp = interface.property(doneProps);
0048             deviceValues.insert(ifaceProp.name(), generateUserString(ifaceProp.name()));
0049         }
0050         values.insert(ifaceDev, deviceValues);
0051     }
0052 
0053     if (includeFiles) {
0054         // Fill the lists of possible device types / device values
0055         // List all the known device actions, then add their name and all values to the appropriate lists
0056 
0057         const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, //
0058                                                            QStringLiteral("/solid/devices/"),
0059                                                            QStandardPaths::LocateDirectory);
0060 
0061         const QStringList files = KFileUtils::findAllUniqueFiles(dirs, {QStringLiteral("*.desktop")});
0062 
0063         for (const QString &file : files) {
0064             KDesktopFile deviceFile(file);
0065             KConfigGroup deviceType = deviceFile.desktopGroup(); // Retrieve the configuration group where the user friendly name is
0066 
0067             const QString ifaceName = deviceType.readEntry("X-KDE-Solid-Actions-Type");
0068             Solid::DeviceInterface::Type ifaceDev = Solid::DeviceInterface::stringToType(ifaceName);
0069             const QString cleanName = Solid::DeviceInterface::typeDescription(ifaceDev);
0070 
0071             types.insert(ifaceDev, cleanName); // Read the user friendly name
0072 
0073             QMap<QString, QString> deviceValues = values.value(ifaceDev);
0074             const auto actions = deviceFile.readActions();
0075             for (const QString &text : actions) { // We want every single action
0076                 KConfigGroup actionType = deviceFile.actionGroup(text);
0077                 deviceValues.insert(text, actionType.readEntry("Name")); // Add to the type - actions map
0078             }
0079             values.insert(ifaceDev, deviceValues);
0080         }
0081     }
0082 }
0083 
0084 QList<QString> SolidActionData::propertyList(Solid::DeviceInterface::Type devInterface)
0085 {
0086     return values.value(devInterface).values();
0087 }
0088 
0089 QList<QString> SolidActionData::propertyInternalList(Solid::DeviceInterface::Type devInterface)
0090 {
0091     return values.value(devInterface).keys();
0092 }
0093 
0094 QString SolidActionData::propertyInternal(Solid::DeviceInterface::Type devInterface, QString property)
0095 {
0096     return values.value(devInterface).key(property);
0097 }
0098 
0099 QString SolidActionData::propertyName(Solid::DeviceInterface::Type devInterface, QString property)
0100 {
0101     return values.value(devInterface).value(property);
0102 }
0103 
0104 int SolidActionData::propertyPosition(Solid::DeviceInterface::Type devInterface, QString property)
0105 {
0106     return values.value(devInterface).keys().indexOf(property);
0107 }
0108 
0109 QList<QString> SolidActionData::interfaceList()
0110 {
0111     return types.values();
0112 }
0113 
0114 QList<Solid::DeviceInterface::Type> SolidActionData::interfaceTypeList()
0115 {
0116     return types.keys();
0117 }
0118 
0119 Solid::DeviceInterface::Type SolidActionData::interfaceFromName(const QString &name)
0120 {
0121     return types.key(name);
0122 }
0123 
0124 QString SolidActionData::nameFromInterface(Solid::DeviceInterface::Type devInterface)
0125 {
0126     return types.value(devInterface);
0127 }
0128 
0129 int SolidActionData::interfacePosition(Solid::DeviceInterface::Type devInterface)
0130 {
0131     return types.keys().indexOf(devInterface);
0132 }
0133 
0134 QString SolidActionData::generateUserString(QString className)
0135 {
0136     QString finalString;
0137     QRegularExpression camelCase(QStringLiteral("([A-Z])")); // Create the split regexp
0138 
0139     finalString = className.remove(0, className.lastIndexOf(':') + 1); // Remove any Class information
0140     finalString.replace(camelCase, QStringLiteral(" \\1")); // Use Camel Casing to add spaces
0141     finalString = KStringHandler::capwords(finalString); // Capitalize everything
0142     return finalString.trimmed();
0143 }
0144 
0145 SolidActionData *SolidActionData::instance()
0146 {
0147     if (actData == nullptr) {
0148         actData = new SolidActionData(true);
0149     }
0150     return actData;
0151 }
0152 
0153 QList<QMetaObject> SolidActionData::fillInterfaceList()
0154 {
0155     QList<QMetaObject> interfaces;
0156     interfaces.append(Solid::Battery::staticMetaObject);
0157     interfaces.append(Solid::Block::staticMetaObject);
0158     interfaces.append(Solid::Camera::staticMetaObject);
0159     interfaces.append(Solid::PortableMediaPlayer::staticMetaObject);
0160     interfaces.append(Solid::Processor::staticMetaObject);
0161     interfaces.append(Solid::StorageAccess::staticMetaObject);
0162     interfaces.append(Solid::StorageDrive::staticMetaObject);
0163     interfaces.append(Solid::OpticalDrive::staticMetaObject);
0164     interfaces.append(Solid::StorageVolume::staticMetaObject);
0165     interfaces.append(Solid::OpticalDisc::staticMetaObject);
0166     return interfaces;
0167 }