2 * SPDX-FileCopyrightText: 2019 Ismael Asensio <isma.af@mgmail.com>
4 * SPDX-License-Identifier: GPL-2.0-or-later
7 #include "dolphinquery.h"
9 #include <QRegularExpression>
11 #include "config-dolphin.h"
13 #include <Baloo/Query>
19 /** Checks if a given term in the Baloo::Query::searchString() is a special search term
20 * @return: the specific search token of the term, or an empty QString() if none is found
22 QString
searchTermToken(const QString
&term
)
24 static const QLatin1String searchTokens
[]{QLatin1String("filename:"),
25 QLatin1String("modified>="),
26 QLatin1String("rating>="),
27 QLatin1String("tag:"),
28 QLatin1String("tag=")};
30 for (const auto &searchToken
: searchTokens
) {
31 if (term
.startsWith(searchToken
)) {
38 QString
stripQuotes(const QString
&text
)
40 if (text
.length() >= 2 && text
.at(0) == QLatin1Char('"') && text
.back() == QLatin1Char('"')) {
41 return text
.mid(1, text
.size() - 2);
46 QStringList
splitOutsideQuotes(const QString
&text
)
48 // Match groups on 3 possible conditions:
49 // - Groups with two leading quotes must close both on them (filename:""abc xyz" tuv")
50 // - Groups enclosed in quotes
51 // - Words separated by spaces
52 static const QRegularExpression
subTermsRegExp("(\\S*?\"\"[^\"]+\"[^\"]+\"+|\\S*?\"[^\"]+\"+|(?<=\\s|^)\\S+(?=\\s|$))");
53 auto subTermsMatchIterator
= subTermsRegExp
.globalMatch(text
);
55 QStringList textParts
;
56 while (subTermsMatchIterator
.hasNext()) {
57 textParts
<< subTermsMatchIterator
.next().captured(0);
63 QString
trimChar(const QString
&text
, const QLatin1Char aChar
)
65 const int start
= text
.startsWith(aChar
) ? 1 : 0;
66 const int end
= (text
.length() > 1 && text
.endsWith(aChar
)) ? 1 : 0;
68 return text
.mid(start
, text
.length() - start
- end
);
72 DolphinQuery
DolphinQuery::fromSearchUrl(const QUrl
&searchUrl
)
75 model
.m_searchUrl
= searchUrl
;
77 if (searchUrl
.scheme() == QLatin1String("baloosearch")) {
78 model
.parseBalooQuery();
79 } else if (searchUrl
.scheme() == QLatin1String("tags")) {
80 // tags can contain # symbols or slashes within the Url
81 QString tag
= trimChar(searchUrl
.toString(QUrl::RemoveScheme
), QLatin1Char('/'));
82 model
.m_searchTerms
<< QStringLiteral("tag:%1").arg(tag
);
88 bool DolphinQuery::supportsScheme(const QString
&urlScheme
)
90 static const QStringList supportedSchemes
= {
91 QStringLiteral("baloosearch"),
92 QStringLiteral("tags"),
95 return supportedSchemes
.contains(urlScheme
);
98 void DolphinQuery::parseBalooQuery()
101 const Baloo::Query query
= Baloo::Query::fromSearchUrl(m_searchUrl
);
103 m_includeFolder
= query
.includeFolder();
105 const QStringList types
= query
.types();
106 m_fileType
= types
.isEmpty() ? QString() : types
.first();
108 QStringList textParts
;
111 const QStringList subTerms
= splitOutsideQuotes(query
.searchString());
112 for (const QString
&subTerm
: subTerms
) {
113 const QString token
= searchTermToken(subTerm
);
114 const QString value
= stripQuotes(subTerm
.mid(token
.length()));
116 if (token
== QLatin1String("filename:")) {
117 if (!value
.isEmpty()) {
119 m_hasFileName
= true;
122 } else if (!token
.isEmpty()) {
123 m_searchTerms
<< token
+ value
;
125 } else if (subTerm
== QLatin1String("AND") && subTerm
!= subTerms
.at(0) && subTerm
!= subTerms
.back()) {
127 } else if (!value
.isEmpty()) {
129 m_hasContentSearch
= true;
134 if (m_hasContentSearch
) {
135 textParts
<< QStringLiteral("filename:\"%1\"").arg(fileName
);
137 textParts
<< fileName
;
141 m_searchText
= textParts
.join(QLatin1Char(' '));
145 QUrl
DolphinQuery::searchUrl() const
150 QString
DolphinQuery::text() const
155 QString
DolphinQuery::type() const
160 QStringList
DolphinQuery::searchTerms() const
162 return m_searchTerms
;
165 QString
DolphinQuery::includeFolder() const
167 return m_includeFolder
;
170 bool DolphinQuery::hasContentSearch() const
172 return m_hasContentSearch
;
175 bool DolphinQuery::hasFileName() const
177 return m_hasFileName
;