]> cloud.milkyroute.net Git - dolphin.git/blob - src/search/dolphinquery.cpp
Fix deprecated knsrc file location
[dolphin.git] / src / search / dolphinquery.cpp
1 /***************************************************************************
2 * Copyright (C) 2019 by Ismael Asensio <isma.af@mgmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include "dolphinquery.h"
21
22 #include <QRegularExpression>
23
24 #include <config-baloo.h>
25 #ifdef HAVE_BALOO
26 #include <Baloo/Query>
27 #endif
28
29 namespace {
30 #ifdef HAVE_BALOO
31 /** Checks if a given term in the Baloo::Query::searchString() is a special search term
32 * @return: the specific search token of the term, or an empty QString() if none is found
33 */
34 QString searchTermToken(const QString& term)
35 {
36 static const QLatin1String searchTokens[] {
37 QLatin1String("filename:"),
38 QLatin1String("modified>="),
39 QLatin1String("rating>="),
40 QLatin1String("tag:"), QLatin1String("tag=")
41 };
42
43 for (const auto &searchToken : searchTokens) {
44 if (term.startsWith(searchToken)) {
45 return searchToken;
46 }
47 }
48 return QString();
49 }
50
51 QString stripQuotes(const QString& text)
52 {
53 if (text.length() >= 2 && text.at(0) == QLatin1Char('"')
54 && text.back() == QLatin1Char('"')) {
55 return text.mid(1, text.size() - 2);
56 }
57 return text;
58 }
59
60 QStringList splitOutsideQuotes(const QString& text)
61 {
62 // Match groups on 3 possible conditions:
63 // - Groups with two leading quotes must close both on them (filename:""abc xyz" tuv")
64 // - Groups enclosed in quotes
65 // - Words separated by spaces
66 const QRegularExpression subTermsRegExp("(\\S*?\"\"[^\"]+\"[^\"]+\"+|\\S*?\"[^\"]+\"+|(?<=\\s|^)\\S+(?=\\s|$))");
67 auto subTermsMatchIterator = subTermsRegExp.globalMatch(text);
68
69 QStringList textParts;
70 while (subTermsMatchIterator.hasNext()) {
71 textParts << subTermsMatchIterator.next().captured(0);
72 }
73 return textParts;
74 }
75 #endif
76 }
77
78
79 DolphinQuery DolphinQuery::fromSearchUrl(const QUrl& searchUrl)
80 {
81 DolphinQuery model;
82 model.m_searchUrl = searchUrl;
83
84 if (searchUrl.scheme() == QLatin1String("baloosearch")) {
85 model.parseBalooQuery();
86 }
87
88 return model;
89 }
90
91 bool DolphinQuery::supportsScheme(const QString& urlScheme)
92 {
93 static const QStringList supportedSchemes = {
94 QStringLiteral("baloosearch"),
95 };
96
97 return supportedSchemes.contains(urlScheme);
98 }
99
100 void DolphinQuery::parseBalooQuery()
101 {
102 #ifdef HAVE_BALOO
103 const Baloo::Query query = Baloo::Query::fromSearchUrl(m_searchUrl);
104
105 m_includeFolder = query.includeFolder();
106
107 const QStringList types = query.types();
108 m_fileType = types.isEmpty() ? QString() : types.first();
109
110 QStringList textParts;
111 QString fileName;
112
113 const QStringList subTerms = splitOutsideQuotes(query.searchString());
114 foreach (const QString& subTerm, subTerms) {
115 const QString token = searchTermToken(subTerm);
116 const QString value = stripQuotes(subTerm.mid(token.length()));
117
118 if (token == QLatin1String("filename:")) {
119 if (!value.isEmpty()) {
120 fileName = value;
121 m_hasFileName = true;
122 }
123 continue;
124 } else if (!token.isEmpty()) {
125 m_searchTerms << token + value;
126 continue;
127 } else if (subTerm == QLatin1String("AND") && subTerm != subTerms.at(0) && subTerm != subTerms.back()) {
128 continue;
129 } else if (!value.isEmpty()) {
130 textParts << value;
131 m_hasContentSearch = true;
132 }
133 }
134
135 if (m_hasFileName) {
136 if (m_hasContentSearch) {
137 textParts << QStringLiteral("filename:\"%1\"").arg(fileName);
138 } else {
139 textParts << fileName;
140 }
141 }
142
143 m_searchText = textParts.join(QLatin1Char(' '));
144 #endif
145 }
146
147
148 QUrl DolphinQuery::searchUrl() const
149 {
150 return m_searchUrl;
151 }
152
153 QString DolphinQuery::text() const
154 {
155 return m_searchText;
156 }
157
158 QString DolphinQuery::type() const
159 {
160 return m_fileType;
161 }
162
163 QStringList DolphinQuery::searchTerms() const
164 {
165 return m_searchTerms;
166 }
167
168 QString DolphinQuery::includeFolder() const
169 {
170 return m_includeFolder;
171 }
172
173 bool DolphinQuery::hasContentSearch() const
174 {
175 return m_hasContentSearch;
176 }
177
178 bool DolphinQuery::hasFileName() const
179 {
180 return m_hasFileName;
181 }