Changeset View
Standalone View
runners/dictionary/dictionaryrunner.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Copyright (C) 2010, 2012 Jason A. Donenfeld <Jason@zx2c4.com> | 2 | * Copyright (C) 2010, 2012 Jason A. Donenfeld <Jason@zx2c4.com> | ||
3 | * Copyright (C) 2020 Alexander Lohnau <alexander.lohnau@gmx.de> | ||||
3 | */ | 4 | */ | ||
4 | 5 | | |||
5 | #include "dictionaryrunner.h" | 6 | #include "dictionaryrunner.h" | ||
7 | #include "config_keys.h" | ||||
6 | 8 | | |||
7 | #include <QStringList> | 9 | #include <QStringList> | ||
8 | #include <klocalizedstring.h> | 10 | #include <KLocalizedString> | ||
9 | | ||||
10 | static const char CONFIG_TRIGGERWORD[] = "triggerWord"; | | |||
11 | 11 | | |||
12 | DictionaryRunner::DictionaryRunner(QObject *parent, const QVariantList &args) | 12 | DictionaryRunner::DictionaryRunner(QObject *parent, const QVariantList &args) | ||
13 | : AbstractRunner(parent, args) | 13 | : AbstractRunner(parent, args) | ||
14 | { | 14 | { | ||
15 | m_engine = new DictionaryMatchEngine(dataEngine(QStringLiteral("dict")), this); | 15 | m_engine = new DictionaryMatchEngine(dataEngine(QStringLiteral("dict")), this); | ||
16 | 16 | | |||
17 | setSpeed(SlowSpeed); | 17 | setSpeed(SlowSpeed); | ||
18 | setPriority(LowPriority); | 18 | setPriority(LowPriority); | ||
19 | setObjectName(QLatin1String("Dictionary")); | 19 | setObjectName(QStringLiteral("Dictionary")); | ||
20 | setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | | 20 | setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | | ||
21 | Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Executable | | 21 | Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Executable | | ||
22 | Plasma::RunnerContext::ShellCommand); | 22 | Plasma::RunnerContext::ShellCommand); | ||
23 | } | | |||
24 | 23 | | |||
25 | void DictionaryRunner::init() | 24 | m_removeHtmlRegex = QRegularExpression(QStringLiteral("<[^>]*>")); | ||
26 | { | 25 | m_partOfSpeechRegex = QRegularExpression(QStringLiteral("(?: ([a-z]{1,5})){0,1} [0-9]{1,2}: (.*)")); | ||
27 | reloadConfiguration(); | 26 | m_removeHtmlRegex.optimize(); | ||
27 | m_partOfSpeechRegex.optimize(); | ||||
28 | } | 28 | } | ||
29 | 29 | | |||
30 | void DictionaryRunner::reloadConfiguration() | 30 | void DictionaryRunner::reloadConfiguration() | ||
31 | { | 31 | { | ||
32 | KConfigGroup c = config(); | 32 | const KConfigGroup c = config(); | ||
33 | m_triggerWord = c.readEntry(CONFIG_TRIGGERWORD, i18nc("Trigger word before word to define", "define")); | 33 | m_triggerWord = c.readEntry(CONFIG_TRIGGERWORD, i18nc("Trigger word before word to define", "define")); | ||
34 | if (!m_triggerWord.isEmpty()) | 34 | if (!m_triggerWord.isEmpty()) { | ||
35 | m_triggerWord.append(QLatin1Char(' ')); | 35 | m_triggerWord = m_triggerWord.simplified().append(QLatin1Char(' ')); | ||
36 | setSyntaxes(QList<Plasma::RunnerSyntax>() << Plasma::RunnerSyntax(Plasma::RunnerSyntax(i18nc("Dictionary keyword", "%1:q:", m_triggerWord), i18n("Finds the definition of :q:.")))); | 36 | } | ||
37 | setSyntaxes({Plasma::RunnerSyntax(Plasma::RunnerSyntax(i18nc("Dictionary keyword", "%1:q:", m_triggerWord), | ||||
sitter: This constructs the same RunnerSyntax twice does it not? | |||||
38 | i18n("Finds the definition of :q:.")))}); | ||||
37 | } | 39 | } | ||
38 | 40 | | |||
39 | void DictionaryRunner::match(Plasma::RunnerContext &context) | 41 | void DictionaryRunner::match(Plasma::RunnerContext &context) | ||
40 | { | 42 | { | ||
41 | QString query = context.query(); | 43 | QString query = context.query(); | ||
42 | if (!query.startsWith(m_triggerWord, Qt::CaseInsensitive)) | 44 | if (!query.startsWith(m_triggerWord, Qt::CaseInsensitive)) { | ||
43 | return; | 45 | return; | ||
46 | } | ||||
44 | query.remove(0, m_triggerWord.length()); | 47 | query.remove(0, m_triggerWord.length()); | ||
45 | if (query.isEmpty()) | 48 | if (query.isEmpty()) { | ||
46 | return; | 49 | return; | ||
50 | } | ||||
47 | QString returnedQuery = m_engine->lookupWord(query); | 51 | QString returnedQuery = m_engine->lookupWord(query); | ||
48 | 52 | | |||
49 | if (!context.isValid()) | 53 | if (!context.isValid()) { | ||
50 | return; | 54 | return; | ||
55 | } | ||||
51 | 56 | | |||
52 | static const QRegExp removeHtml(QLatin1String("<[^>]*>")); | | |||
53 | QString definitions(returnedQuery); | 57 | QString definitions(returnedQuery); | ||
54 | definitions.remove(QLatin1Char('\r')).remove(removeHtml); | 58 | definitions.remove(QLatin1Char('\r')).remove(m_removeHtmlRegex); | ||
55 | while (definitions.contains(QLatin1String(" "))) | 59 | while (definitions.contains(QLatin1String(" "))) { | ||
56 | definitions.replace(QLatin1String(" "), QLatin1String(" ")); | 60 | definitions.replace(QLatin1String(" "), QLatin1String(" ")); | ||
61 | } | ||||
57 | #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) | 62 | #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) | ||
58 | QStringList lines = definitions.split(QLatin1Char('\n'), QString::SkipEmptyParts); | 63 | QStringList lines = definitions.split(QLatin1Char('\n'), QString::SkipEmptyParts); | ||
59 | #else | 64 | #else | ||
60 | QStringList lines = definitions.split(QLatin1Char('\n'), Qt::SkipEmptyParts); | 65 | QStringList lines = definitions.split(QLatin1Char('\n'), Qt::SkipEmptyParts); | ||
61 | #endif | 66 | #endif | ||
62 | if (lines.length() < 2) | 67 | if (lines.length() < 2) { | ||
63 | return; | 68 | return; | ||
69 | } | ||||
64 | lines.removeFirst(); | 70 | lines.removeFirst(); | ||
65 | 71 | | |||
66 | QList<Plasma::QueryMatch> matches; | 72 | QList<Plasma::QueryMatch> matches; | ||
67 | int item = 0; | 73 | int item = 0; | ||
68 | static const QRegExp partOfSpeech(QLatin1String("(?: ([a-z]{1,5})){0,1} [0-9]{1,2}: (.*)")); | | |||
69 | QString lastPartOfSpeech; | 74 | QString lastPartOfSpeech; | ||
70 | foreach (const QString &line, lines) { | 75 | for (const QString &line: qAsConst(lines)) { | ||
sitter: ` : ` | |||||
71 | if (partOfSpeech.indexIn(line) == -1) | 76 | const QRegularExpressionMatch partOfSpeechMatch = m_partOfSpeechRegex.match(line); | ||
77 | if (!partOfSpeechMatch.hasMatch()) { | ||||
72 | continue; | 78 | continue; | ||
73 | if (!partOfSpeech.cap(1).isEmpty()) | 79 | } | ||
74 | lastPartOfSpeech = partOfSpeech.cap(1); | 80 | if (!partOfSpeechMatch.captured(1).isEmpty()) { | ||
81 | lastPartOfSpeech = partOfSpeechMatch.captured(1); | ||||
82 | } | ||||
75 | Plasma::QueryMatch match(this); | 83 | Plasma::QueryMatch match(this); | ||
76 | match.setText(query + QLatin1String(": ") + lastPartOfSpeech); | 84 | match.setText(query + QLatin1String(": ") + lastPartOfSpeech); | ||
77 | match.setRelevance(1 - (static_cast<double>(++item) / static_cast<double>(lines.length()))); | 85 | match.setRelevance(1 - (static_cast<double>(++item) / static_cast<double>(lines.length()))); | ||
78 | match.setType(Plasma::QueryMatch::InformationalMatch); | 86 | match.setType(Plasma::QueryMatch::InformationalMatch); | ||
79 | match.setIconName(QStringLiteral("accessories-dictionary")); | 87 | match.setIconName(QStringLiteral("accessories-dictionary")); | ||
80 | match.setSubtext(partOfSpeech.cap(2)); | 88 | match.setSubtext(partOfSpeechMatch.captured(2)); | ||
89 | // TODO What to set as data? | ||||
90 | //match.setData(QVariant()); | ||||
You could simply use the lastPartOfSpeech I would guess. From what I've seen and what Kai tells me you really only need to set setData if you want to implement actions (::actionsForMatch) and need to carry some information to figure out what the match result was or what its actions ought to be, or runability (::run). The latter in fact only appears to need id() so it can persistently track how often a given thing was run and thus give it higher relevance if the user chooses that option a lot. sitter: You could simply use the lastPartOfSpeech I would guess. From what I've seen and what Kai tells… | |||||
The current behavior is that KRunner closes when a match is selected. So the runner would benefit from setData, or am I missing something? alex: The current behavior is that KRunner closes when a match is selected.
But if you set the data… | |||||
Entirely possible, @broulik knows way more about the UI code. If data is used in the UI then that would run counter to its purpose though. Sets data to be used internally by the associated AbstractRunner. putting a string into the UI is not internal anymore ^^ sitter: Entirely possible, @broulik knows way more about the UI code. If data is used in the UI then… | |||||
81 | matches.append(match); | 91 | matches.append(match); | ||
82 | } | 92 | } | ||
83 | context.addMatches(matches); | 93 | context.addMatches(matches); | ||
84 | } | 94 | } | ||
85 | 95 | | |||
86 | K_EXPORT_PLASMA_RUNNER(krunner_dictionary, DictionaryRunner) | 96 | K_EXPORT_PLASMA_RUNNER(krunner_dictionary, DictionaryRunner) | ||
87 | 97 | | |||
88 | #include "dictionaryrunner.moc" | 98 | #include "dictionaryrunner.moc" |
This constructs the same RunnerSyntax twice does it not?