File indexing completed on 2024-05-12 05:38:19

0001 /*
0002     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
0003     SPDX-License-Identifier: LGPL-2.1-or-later
0004 */
0005 
0006 #include "helprunner.h"
0007 
0008 #include <KIO/CommandLauncherJob>
0009 #include <KLocalizedString>
0010 #include <KPluginMetaData>
0011 #include <qttypetraits.h>
0012 
0013 HelpRunner::HelpRunner(QObject *parent, const KPluginMetaData &pluginMetaData)
0014     : AbstractRunner(parent, pluginMetaData)
0015     , m_actionList({Action(QStringLiteral("configure"), i18n("Configure plugin"), QStringLiteral("configure"))})
0016 {
0017     setTriggerWords({i18nc("this is a runner keyword", "help"), QStringLiteral("?")});
0018     m_manager = qobject_cast<RunnerManager *>(parent);
0019     Q_ASSERT(m_manager);
0020 }
0021 
0022 void HelpRunner::match(RunnerContext &context)
0023 {
0024     const QString sanatizedQuery = context.query().remove(matchRegex());
0025     auto runners = m_manager->runners();
0026     for (auto it = runners.begin(); it != runners.end();) {
0027         if (*it == this || (*it)->syntaxes().isEmpty()) {
0028             it = runners.erase(it);
0029         } else {
0030             ++it;
0031         }
0032     }
0033 
0034     QList<AbstractRunner *> matchingRunners;
0035     if (sanatizedQuery.isEmpty()) {
0036         matchingRunners = runners;
0037     } else {
0038         for (AbstractRunner *runner : std::as_const(runners)) {
0039             if (runner->id().contains(sanatizedQuery, Qt::CaseInsensitive) || runner->name().contains(sanatizedQuery, Qt::CaseInsensitive)) {
0040                 matchingRunners << runner;
0041             }
0042         }
0043     }
0044     QList<QueryMatch> matches;
0045     bool showExtendedHelp = matchingRunners.count() == 1 && sanatizedQuery.count() >= 3;
0046     for (AbstractRunner *runner : std::as_const(matchingRunners)) {
0047         const QList<RunnerSyntax> syntaxes = runner->syntaxes();
0048         if (showExtendedHelp) {
0049             float i = 1;
0050             for (const RunnerSyntax &syntax : syntaxes) {
0051                 QueryMatch match(this);
0052                 // Set relevance to preserve the original order of the syntaxes
0053                 match.setRelevance(1 / i);
0054                 i++;
0055                 QString matchText;
0056                 QString text = QLatin1String("<b>");
0057                 const auto exampleQueries = syntax.exampleQueries();
0058                 for (auto &query : exampleQueries) {
0059                     text.append(query.toHtmlEscaped());
0060                     text.append(QLatin1String("<br>"));
0061                 }
0062                 text.append(QLatin1String("</b>"));
0063                 matchText.append(text);
0064                 matchText.append(syntax.description().toHtmlEscaped());
0065                 match.setText(matchText);
0066                 match.setData(syntax.exampleQueries().constFirst());
0067                 match.setMultiLine(true);
0068                 match.setMatchCategory(runner->name());
0069                 match.setIconName(runner->metadata().iconName());
0070                 matches << match;
0071             }
0072         } else {
0073             QueryMatch match(this);
0074             if (runner->metadata().value(QStringLiteral("X-Plasma-ShowDesciptionInOverview"), false)) {
0075                 match.setText(runner->metadata().description());
0076             } else {
0077                 match.setText(syntaxes.constFirst().exampleQueries().constFirst());
0078                 match.setSubtext(runner->metadata().description());
0079             }
0080             match.setIconName(runner->metadata().iconName());
0081             match.setCategoryRelevance(QueryMatch::CategoryRelevance::Low);
0082             match.setData(QVariant::fromValue(runner->metadata()));
0083             if (!runner->metadata().value(QStringLiteral("X-KDE-ConfigModule")).isEmpty()) {
0084                 match.setActions(m_actionList);
0085             }
0086             matches << match;
0087         }
0088     }
0089     context.addMatches(matches);
0090 }
0091 
0092 void HelpRunner::run(const RunnerContext &context, const QueryMatch &match)
0093 {
0094     context.ignoreCurrentMatchForHistory();
0095     if (match.selectedAction()) {
0096         KIO::CommandLauncherJob *job = nullptr;
0097         const QStringList args{
0098             QStringLiteral("kcm_plasmasearch"),
0099             QStringLiteral("--args"),
0100             match.data().value<KPluginMetaData>().pluginId(),
0101         };
0102         job = new KIO::CommandLauncherJob(QStringLiteral("systemsettings"), args);
0103         job->start();
0104     } else if (match.categoryRelevance() == qToUnderlying(QueryMatch::CategoryRelevance::Low)) {
0105         const KPluginMetaData data = match.data().value<KPluginMetaData>();
0106         const QString completedRunnerName = QStringLiteral("?") + data.name();
0107         context.requestQueryStringUpdate(completedRunnerName, -1);
0108     } else {
0109         const QString query = match.data().toString();
0110         static const QRegularExpression placeholderRegex{QStringLiteral("<.+>$")};
0111         const int idx = query.indexOf(placeholderRegex);
0112         context.requestQueryStringUpdate(query, idx == -1 ? query.count() : idx);
0113     }
0114 }
0115 
0116 K_PLUGIN_CLASS_WITH_JSON(HelpRunner, "helprunner.json")
0117 
0118 #include "helprunner.moc"