1 | /* |
---|---|
2 | SPDX-FileCopyrightText: 2000 Malte Starostik <malte@kde.org> |
3 | |
4 | SPDX-License-Identifier: GPL-2.0-or-later |
5 | */ |
6 | |
7 | #include "searchprovider.h" |
8 | |
9 | #include <KConfigGroup> |
10 | #include <KDesktopFile> |
11 | #include <KIO/Global> // KIO::iconNameForUrl |
12 | #include <KRandom> |
13 | #include <KService> |
14 | #include <QFileInfo> |
15 | #include <QStandardPaths> |
16 | |
17 | SearchProvider::SearchProvider(const QString &servicePath) |
18 | : m_dirty(false) |
19 | { |
20 | setDesktopEntryName(QFileInfo(servicePath).baseName()); |
21 | KDesktopFile parser(servicePath); |
22 | setName(parser.readName()); |
23 | KConfigGroup group(parser.desktopGroup()); |
24 | setKeys(group.readEntry(key: "Keys", aDefault: QStringList())); |
25 | |
26 | m_query = group.readEntry(key: "Query"); |
27 | m_charset = group.readEntry(key: "Charset"); |
28 | m_iconName = group.readEntry(key: "Icon"); |
29 | m_isHidden = group.readEntry(key: "Hidden", defaultValue: false); |
30 | } |
31 | |
32 | SearchProvider::~SearchProvider() |
33 | { |
34 | } |
35 | |
36 | void SearchProvider::setName(const QString &name) |
37 | { |
38 | if (KUriFilterSearchProvider::name() == name) { |
39 | return; |
40 | } |
41 | |
42 | KUriFilterSearchProvider::setName(name); |
43 | } |
44 | |
45 | void SearchProvider::setQuery(const QString &query) |
46 | { |
47 | if (m_query == query) { |
48 | return; |
49 | } |
50 | |
51 | m_query = query; |
52 | } |
53 | |
54 | void SearchProvider::setKeys(const QStringList &keys) |
55 | { |
56 | if (KUriFilterSearchProvider::keys() == keys) { |
57 | return; |
58 | } |
59 | |
60 | KUriFilterSearchProvider::setKeys(keys); |
61 | |
62 | QString name = desktopEntryName(); |
63 | if (!name.isEmpty()) { |
64 | return; |
65 | } |
66 | |
67 | // New provider. Set the desktopEntryName. |
68 | // Take the longest search shortcut as filename, |
69 | // if such a file already exists, append a number and increase it |
70 | // until the name is unique |
71 | for (const QString &key : keys) { |
72 | if (key.length() > name.length()) { |
73 | // We should avoid hidden files and directory paths, BUG: 407944 |
74 | name = key.toLower().remove(c: QLatin1Char('.')).remove(c: QLatin1Char('/')); |
75 | ; |
76 | } |
77 | } |
78 | |
79 | const QString path = QStandardPaths::writableLocation(type: QStandardPaths::GenericDataLocation) + QLatin1String("/kf6/searchproviders/"); |
80 | bool firstRun = true; |
81 | |
82 | while (true) { |
83 | QString check(name); |
84 | |
85 | if (!firstRun) { |
86 | check += KRandom::randomString(length: 4); |
87 | } |
88 | |
89 | const QString located = |
90 | QStandardPaths::locate(type: QStandardPaths::GenericDataLocation, fileName: QLatin1String("kf6/searchproviders/") + check + QLatin1String( ".desktop")); |
91 | if (located.isEmpty()) { |
92 | name = check; |
93 | break; |
94 | } else if (located.startsWith(s: path)) { |
95 | // If it's a deleted (hidden) entry, overwrite it |
96 | if (KService(located).isDeleted()) { |
97 | break; |
98 | } |
99 | } |
100 | firstRun = false; |
101 | } |
102 | |
103 | setDesktopEntryName(name); |
104 | } |
105 | |
106 | void SearchProvider::setCharset(const QString &charset) |
107 | { |
108 | if (m_charset == charset) { |
109 | return; |
110 | } |
111 | |
112 | m_charset = charset; |
113 | } |
114 | |
115 | QString SearchProvider::iconName() const |
116 | { |
117 | if (!m_iconName.isEmpty()) { |
118 | return m_iconName; |
119 | } |
120 | |
121 | return KIO::iconNameForUrl(url: QUrl(m_query)); |
122 | } |
123 | |
124 | void SearchProvider::setDirty(bool dirty) |
125 | { |
126 | m_dirty = dirty; |
127 | } |
128 |