Warning, file /education/cantor/src/lib/backend.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2009 Alexander Rieder <alexanderrieder@gmail.com>
0004 */
0005 
0006 #include <vector>
0007 
0008 #include "backend.h"
0009 #include "extension.h"
0010 
0011 #include <QDir>
0012 #include <QRegularExpression>
0013 #include <QUrl>
0014 #include <QProcess>
0015 #include <QStandardPaths>
0016 #include <QPluginLoader>
0017 
0018 #include <KPluginFactory>
0019 #include <KPluginMetaData>
0020 #include <KPluginFactory>
0021 #include <KLocalizedString>
0022 
0023 using namespace Cantor;
0024 
0025 class Cantor::BackendPrivate
0026 {
0027   public:
0028     QString name;
0029     QString comment;
0030     QString icon;
0031     QString url;
0032     bool enabled{true};
0033     QList<GraphicPackage> supportedGraphicPackagesCache;
0034 };
0035 
0036 Backend::Backend(QObject* parent, const QList<QVariant>& args) : QObject(parent),
0037                                                                 d(new BackendPrivate)
0038 {
0039     Q_UNUSED(args)
0040 }
0041 
0042 Backend::~Backend()
0043 {
0044     delete d;
0045 }
0046 
0047 QString Backend::name() const
0048 {
0049     return d->name;
0050 }
0051 
0052 QString Backend::comment() const
0053 {
0054     return d->comment;
0055 }
0056 
0057 QString Backend::description() const
0058 {
0059     return comment();
0060 }
0061 
0062 QString Backend::icon() const
0063 {
0064     return d->icon;
0065 }
0066 
0067 QString Backend::url() const
0068 {
0069     return d->url;
0070 }
0071 
0072 QString Backend::defaultHelp() const
0073 {
0074     return QString();
0075 }
0076 
0077 bool Backend::isEnabled() const
0078 {
0079     return d->enabled && requirementsFullfilled();
0080 }
0081 
0082 void Backend::setEnabled(bool enabled)
0083 {
0084     d->enabled = enabled;
0085 }
0086 
0087 QStringList Backend::listAvailableBackends()
0088 {
0089     QStringList l;
0090     for (Backend* b : availableBackends())
0091     {
0092         if(b->isEnabled())
0093             l<<b->name();
0094     }
0095 
0096     return l;
0097 }
0098 
0099 QList<Backend*> Backend::availableBackends()
0100 {
0101     static QList<Backend*> backendCache;
0102     //if we already have all backends Cached, just return the cache.
0103     //otherwise create the available backends
0104     if(!backendCache.isEmpty())
0105     {
0106         return backendCache;
0107     }
0108 
0109     const QVector<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("cantor/backends"));
0110 
0111     for (const KPluginMetaData &plugin : plugins) {
0112 
0113         const auto result = KPluginFactory::instantiatePlugin<Backend>(plugin, QCoreApplication::instance());
0114 
0115         if (!result) {
0116             qDebug() << "Error while loading backend: " << result.errorText;
0117             continue;
0118         }
0119 
0120         Backend *backend = result.plugin;
0121 
0122         backend->d->name = plugin.name();
0123         backend->d->comment = plugin.description();
0124         backend->d->icon = plugin.iconName();
0125         backend->d->url = plugin.website();
0126         backendCache << backend;
0127     }
0128 
0129     return backendCache;
0130 }
0131 
0132 Backend* Backend::getBackend(const QString& name)
0133 {
0134     for (Backend* b : availableBackends())
0135     {
0136         if(b->name().toLower()==name.toLower() || b->id().toLower()==name.toLower())
0137             return b;
0138     }
0139 
0140     return nullptr;
0141 }
0142 
0143 QStringList Backend::extensions() const
0144 {
0145     QList<Extension*> extensions = findChildren<Extension*>(QRegularExpression(QLatin1String(".*Extension")));
0146     QStringList names;
0147     for (Extension* e : extensions)
0148         names << e->objectName();
0149     return names;
0150 }
0151 
0152 Extension* Backend::extension(const QString& name) const
0153 {
0154     return findChild<Extension*>(name);
0155 }
0156 
0157 bool Backend::checkExecutable(const QString& name, const QString& path, QString* reason)
0158 {
0159     if (path.isEmpty())
0160     {
0161         if (reason)
0162             *reason = i18n("No path for the %1 executable specified. "
0163                         "Please provide the correct path in the application settings and try again.",
0164                         name);
0165         return false;
0166     }
0167 
0168     QFileInfo info(path);
0169     if (!info.exists())
0170     {
0171         if (reason)
0172             *reason = i18n("The specified file '%1' for the %2 executable doesn't exist. "
0173                         "Please provide the correct path in the application settings and try again.",
0174                         path, name);
0175         return false;
0176     }
0177 
0178     if (!info.isExecutable())
0179     {
0180         if (reason)
0181             *reason = i18n("The specified file '%1' doesn't point to an executable. "
0182                         "Please provide the correct path in the application settings and try again.",
0183                         path);
0184         return false;
0185     }
0186 
0187     return true;
0188 }
0189 
0190 bool Cantor::Backend::testProgramWritable(const QString& program, const QStringList& args, const QString& filename, const QString& expectedContent, QString* reason, int timeOut)
0191 {
0192     QProcess process;
0193     process.setProgram(program);
0194     process.setArguments(args);
0195     process.start();
0196 
0197     if (process.waitForFinished(timeOut) == false)
0198     {
0199         if (reason)
0200             *reason = i18n("The program %1 didn't finish the execution after %2 milliseconds during the plot integration test.", QFileInfo(program).fileName(), timeOut);
0201 
0202         return false;
0203     }
0204 
0205     QFile file(filename);
0206     if (!file.open(QIODevice::ReadOnly))
0207     {
0208         if (reason)
0209             *reason = i18n("Failed to open the file %1 during the plot integration test.", filename);
0210         return false;
0211     }
0212 
0213     QString fileContent = QString::fromLocal8Bit(file.readAll());
0214     if (fileContent.trimmed() != expectedContent)
0215     {
0216         if (reason)
0217             *reason = i18n("Failed to parse the result during the plot integration test.");
0218         return false;
0219     }
0220 
0221     file.close();
0222     file.remove();
0223 
0224     return true;
0225 }
0226 
0227 QList<GraphicPackage> Backend::availableGraphicPackages() const
0228 {
0229     if (d->supportedGraphicPackagesCache.size() != 0)
0230         return d->supportedGraphicPackagesCache;
0231 
0232     if (!(capabilities() & Capability::IntegratedPlots))
0233         return QList<GraphicPackage>(); // because this cache is empty
0234 
0235     QString packagesFile = id() + QLatin1String("/graphic_packages.xml");
0236     QString filename = QStandardPaths::locate(QStandardPaths::AppDataLocation, packagesFile, QStandardPaths::LocateFile);
0237 
0238     if (filename.isEmpty())
0239         filename = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("cantor/") + packagesFile, QStandardPaths::LocateFile);
0240 
0241     if (filename.isEmpty())
0242         return QList<GraphicPackage>();
0243 
0244     d->supportedGraphicPackagesCache = GraphicPackage::loadFromFile(filename);
0245 
0246     return d->supportedGraphicPackagesCache;
0247 }