mirror of
https://invent.kde.org/system/dolphin
synced 2024-08-22 01:40:02 +00:00
Merge branch 'release/19.12'
This commit is contained in:
commit
6bcdb62429
|
@ -216,6 +216,7 @@ set(dolphinstatic_SRCS
|
|||
panels/folders/folderspanel.cpp
|
||||
panels/terminal/terminalpanel.cpp
|
||||
search/dolphinfacetswidget.cpp
|
||||
search/dolphinquery.cpp
|
||||
search/dolphinsearchbox.cpp
|
||||
settings/general/behaviorsettingspage.cpp
|
||||
settings/general/configurepreviewplugindialog.cpp
|
||||
|
|
|
@ -523,7 +523,7 @@
|
|||
<li xml:lang="zh-TW">復原支援</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url type="homepage">https://dolphin.kde.org/</url>
|
||||
<url type="homepage">https://kde.org/applications/system/dolphin</url>
|
||||
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&product=dolphin</url>
|
||||
<url type="help">https://docs.kde.org/?application=dolphin</url>
|
||||
<url type="donation">https://www.kde.org/community/donations/?app=dolphin&source=appdata</url>
|
||||
|
|
|
@ -153,7 +153,7 @@ void DolphinFacetsWidget::setRatingTerm(const QString& term)
|
|||
|
||||
void DolphinFacetsWidget::setFacetType(const QString& type)
|
||||
{
|
||||
for (int index = 1; index <= m_typeSelector->count(); index++) {
|
||||
for (int index = 0; index <= m_typeSelector->count(); index++) {
|
||||
if (type == m_typeSelector->itemData(index).toString()) {
|
||||
m_typeSelector->setCurrentIndex(index);
|
||||
break;
|
||||
|
|
98
src/search/dolphinquery.cpp
Normal file
98
src/search/dolphinquery.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2019 by Ismael Asensio <isma.af@mgmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
||||
***************************************************************************/
|
||||
|
||||
#include "dolphinquery.h"
|
||||
|
||||
#include <config-baloo.h>
|
||||
#ifdef HAVE_BALOO
|
||||
#include <Baloo/Query>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
/** Checks if a given term in the Baloo::Query::searchString() is a special search term.
|
||||
* This is a copy of `DolphinFacetsWidget::isRatingTerm()` method.
|
||||
*/
|
||||
bool isSearchTerm(const QString& term)
|
||||
{
|
||||
static const QLatin1String searchTokens[] {
|
||||
QLatin1String("modified>="),
|
||||
QLatin1String("rating>=")
|
||||
};
|
||||
|
||||
for (const auto &searchToken : searchTokens) {
|
||||
if (term.startsWith(searchToken)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DolphinQuery DolphinQuery::fromBalooSearchUrl(const QUrl& searchUrl)
|
||||
{
|
||||
DolphinQuery model;
|
||||
model.m_searchUrl = searchUrl;
|
||||
|
||||
#ifdef HAVE_BALOO
|
||||
const Baloo::Query query = Baloo::Query::fromSearchUrl(searchUrl);
|
||||
|
||||
model.m_includeFolder = query.includeFolder();
|
||||
|
||||
model.m_searchText = query.searchString();
|
||||
|
||||
const QStringList types = query.types();
|
||||
model.m_fileType = types.isEmpty() ? QString() : types.first();
|
||||
|
||||
const QStringList subTerms = query.searchString().split(' ', QString::SkipEmptyParts);
|
||||
foreach (const QString& subTerm, subTerms) {
|
||||
if (subTerm.startsWith(QLatin1String("filename:"))) {
|
||||
const QString value = subTerm.mid(9);
|
||||
model.m_searchText = value;
|
||||
} else if (isSearchTerm(subTerm)) {
|
||||
model.m_searchTerms << subTerm;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return model;
|
||||
}
|
||||
|
||||
QUrl DolphinQuery::searchUrl() const
|
||||
{
|
||||
return m_searchUrl;
|
||||
}
|
||||
|
||||
QString DolphinQuery::text() const
|
||||
{
|
||||
return m_searchText;
|
||||
}
|
||||
|
||||
QString DolphinQuery::type() const
|
||||
{
|
||||
return m_fileType;
|
||||
}
|
||||
|
||||
QStringList DolphinQuery::searchTerms() const
|
||||
{
|
||||
return m_searchTerms;
|
||||
}
|
||||
|
||||
QString DolphinQuery::includeFolder() const
|
||||
{
|
||||
return m_includeFolder;
|
||||
}
|
60
src/search/dolphinquery.h
Normal file
60
src/search/dolphinquery.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2019 by Ismael Asensio <isma.af@mgmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DOLPHINQUERY_H
|
||||
#define DOLPHINQUERY_H
|
||||
|
||||
#include "dolphin_export.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
/**
|
||||
* @brief Simple query model that parses a Baloo search Url and extracts its
|
||||
* separate components to be displayed on dolphin search box.
|
||||
*/
|
||||
class DolphinQuery
|
||||
{
|
||||
public:
|
||||
/** Calls Baloo::Query::fromSearchUrl() with the given @p searchUrl
|
||||
* and parses the result to extract its separate components */
|
||||
static DolphinQuery fromBalooSearchUrl(const QUrl& searchUrl);
|
||||
|
||||
/** @return the \a searchUrl passed to Baloo::Query::fromSearchUrl() */
|
||||
QUrl searchUrl() const;
|
||||
/** @return the user text part of the query, to be shown in the searchbar */
|
||||
QString text() const;
|
||||
/** @return the first of Baloo::Query::types(), or an empty string */
|
||||
QString type() const;
|
||||
/** @return a list of the search terms of the Baloo::Query that act as a filter,
|
||||
* such as \"rating>= <i>value<i>\" or \"modified>= <i>date<i>\"*/
|
||||
QStringList searchTerms() const;
|
||||
/** @return Baloo::Query::includeFolder(), that is, the initial directory
|
||||
* for the query or an empty string if its a global search" */
|
||||
QString includeFolder() const;
|
||||
|
||||
private:
|
||||
QUrl m_searchUrl;
|
||||
QString m_searchText;
|
||||
QString m_fileType;
|
||||
QStringList m_searchTerms;
|
||||
QString m_includeFolder;
|
||||
};
|
||||
|
||||
#endif //DOLPHINQUERY_H
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "dolphin_searchsettings.h"
|
||||
#include "dolphinfacetswidget.h"
|
||||
#include "dolphinquery.h"
|
||||
#include "panels/places/placesitemmodel.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
@ -143,7 +144,8 @@ QUrl DolphinSearchBox::urlForSearching() const
|
|||
void DolphinSearchBox::fromSearchUrl(const QUrl& url)
|
||||
{
|
||||
if (url.scheme() == QLatin1String("baloosearch")) {
|
||||
fromBalooSearchUrl(url);
|
||||
const DolphinQuery query = DolphinQuery::fromBalooSearchUrl(url);
|
||||
updateFromQuery(query);
|
||||
} else if (url.scheme() == QLatin1String("filenamesearch")) {
|
||||
const QUrlQuery query(url);
|
||||
setText(query.queryItemValue(QStringLiteral("search")));
|
||||
|
@ -498,11 +500,8 @@ QUrl DolphinSearchBox::balooUrlForSearching() const
|
|||
#endif
|
||||
}
|
||||
|
||||
void DolphinSearchBox::fromBalooSearchUrl(const QUrl& url)
|
||||
void DolphinSearchBox::updateFromQuery(const DolphinQuery& query)
|
||||
{
|
||||
#ifdef HAVE_BALOO
|
||||
const Baloo::Query query = Baloo::Query::fromSearchUrl(url);
|
||||
|
||||
// Block all signals to avoid unnecessary "searchRequest" signals
|
||||
// while we adjust the search text and the facet widget.
|
||||
blockSignals(true);
|
||||
|
@ -514,30 +513,17 @@ void DolphinSearchBox::fromBalooSearchUrl(const QUrl& url)
|
|||
setSearchPath(QUrl::fromLocalFile(QDir::homePath()));
|
||||
}
|
||||
|
||||
setText(query.text());
|
||||
|
||||
m_facetsWidget->resetOptions();
|
||||
|
||||
setText(query.searchString());
|
||||
|
||||
QStringList types = query.types();
|
||||
if (!types.isEmpty()) {
|
||||
m_facetsWidget->setFacetType(types.first());
|
||||
}
|
||||
|
||||
const QStringList subTerms = query.searchString().split(' ', QString::SkipEmptyParts);
|
||||
foreach (const QString& subTerm, subTerms) {
|
||||
if (subTerm.startsWith(QLatin1String("filename:"))) {
|
||||
const QString value = subTerm.mid(9);
|
||||
setText(value);
|
||||
} else if (m_facetsWidget->isRatingTerm(subTerm)) {
|
||||
m_facetsWidget->setRatingTerm(subTerm);
|
||||
}
|
||||
m_facetsWidget->setFacetType(query.type());
|
||||
const QStringList searchTerms = query.searchTerms();
|
||||
for (const QString& searchTerm : searchTerms) {
|
||||
m_facetsWidget->setRatingTerm(searchTerm);
|
||||
}
|
||||
|
||||
m_startSearchTimer->stop();
|
||||
blockSignals(false);
|
||||
#else
|
||||
Q_UNUSED(url)
|
||||
#endif
|
||||
}
|
||||
|
||||
void DolphinSearchBox::updateFacetsVisible()
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QWidget>
|
||||
|
||||
class DolphinFacetsWidget;
|
||||
class DolphinQuery;
|
||||
class QLineEdit;
|
||||
class KSeparator;
|
||||
class QToolButton;
|
||||
|
@ -152,10 +153,9 @@ private:
|
|||
QUrl balooUrlForSearching() const;
|
||||
|
||||
/**
|
||||
* Extracts information from the given Baloo search \a url to
|
||||
* initialize the search box properly.
|
||||
* Sets the searchbox UI with the parameters established by the \a query
|
||||
*/
|
||||
void fromBalooSearchUrl(const QUrl& url);
|
||||
void updateFromQuery(const DolphinQuery& query);
|
||||
|
||||
void updateFacetsVisible();
|
||||
|
||||
|
|
|
@ -49,6 +49,13 @@ if (KF5Baloo_FOUND)
|
|||
LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
|
||||
endif()
|
||||
|
||||
# DolphinQuery
|
||||
if (KF5Baloo_FOUND)
|
||||
ecm_add_test(dolphinquerytest.cpp
|
||||
TEST_NAME dolphinquerytest
|
||||
LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
|
||||
endif()
|
||||
|
||||
# KStandardItemModelTest
|
||||
ecm_add_test(kstandarditemmodeltest.cpp
|
||||
TEST_NAME kstandarditemmodeltest
|
||||
|
|
147
src/tests/dolphinquerytest.cpp
Normal file
147
src/tests/dolphinquerytest.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2019 by Ismael Asensio <isma.af@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
||||
***************************************************************************/
|
||||
|
||||
#include "search/dolphinquery.h"
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
class DolphinSearchBoxTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void testBalooSearchParsing_data();
|
||||
void testBalooSearchParsing();
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the parameters for the test cases in testBalooSearchParsing()
|
||||
*/
|
||||
void DolphinSearchBoxTest::testBalooSearchParsing_data()
|
||||
{
|
||||
const QString text = QStringLiteral("xyz");
|
||||
const QString filename = QStringLiteral("filename:\"xyz\"");
|
||||
const QString rating = QStringLiteral("rating>=2");
|
||||
const QString modified = QString("modified>=2019-08-07");
|
||||
|
||||
QTest::addColumn<QString>("searchString");
|
||||
QTest::addColumn<QString>("expectedText");
|
||||
QTest::addColumn<QStringList>("expectedTerms");
|
||||
|
||||
// Test for "Content"
|
||||
QTest::newRow("content") << text << text << QStringList();
|
||||
QTest::newRow("content/empty") << "" << "" << QStringList();
|
||||
QTest::newRow("content/singleQuote") << "\"" << "" << QStringList();
|
||||
QTest::newRow("content/doubleQuote") << "\"\"" << "" << QStringList();
|
||||
// Test for empty `filename`
|
||||
QTest::newRow("filename") << filename << text << QStringList();
|
||||
QTest::newRow("filename/empty") << "filename:" << "" << QStringList();
|
||||
QTest::newRow("filename/singleQuote") << "filename:\"" << "" << QStringList();
|
||||
QTest::newRow("filename/doubleQuote") << "filename:\"\"" << "" << QStringList();
|
||||
|
||||
// Test for rating
|
||||
QTest::newRow("rating") << rating << "" << QStringList({rating});
|
||||
QTest::newRow("rating+content") << rating + " " + text << text << QStringList({rating});
|
||||
QTest::newRow("rating+filename") << rating + " " + filename << text << QStringList({rating});
|
||||
// Test for modified date
|
||||
QTest::newRow("modified") << modified << "" << QStringList({modified});
|
||||
QTest::newRow("modified+content") << modified + " " + text << text << QStringList({modified});
|
||||
QTest::newRow("modified+filename") << modified + " " + filename << text << QStringList({modified});
|
||||
// Combined tests
|
||||
QTest::newRow("rating+modified") << rating + " AND " + modified << "" << QStringList({modified, rating});
|
||||
QTest::newRow("rating+modified+content") << rating + " AND " + modified + " " + text << text << QStringList({modified, rating});
|
||||
QTest::newRow("rating+modified+filename") << rating + " AND " + modified + " " + filename << text << QStringList({modified, rating});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to compose the baloo query URL used for searching
|
||||
*/
|
||||
QUrl composeQueryUrl(const QString& searchString)
|
||||
{
|
||||
const QJsonObject jsonObject {
|
||||
{"searchString", searchString}
|
||||
};
|
||||
|
||||
const QJsonDocument doc(jsonObject);
|
||||
const QString queryString = QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem(QStringLiteral("json"), queryString);
|
||||
|
||||
QUrl searchUrl;
|
||||
searchUrl.setScheme(QLatin1String("baloosearch"));
|
||||
searchUrl.setQuery(urlQuery);
|
||||
|
||||
return searchUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* The test verifies whether the different terms of a Baloo search URL ("baloosearch:") are
|
||||
* properly handled by the searchbox, and only "user" or filename terms are added to the
|
||||
* text bar of the searchbox.
|
||||
*/
|
||||
void DolphinSearchBoxTest::testBalooSearchParsing()
|
||||
{
|
||||
QFETCH(QString, searchString);
|
||||
QFETCH(QString, expectedText);
|
||||
QFETCH(QStringList, expectedTerms);
|
||||
|
||||
const QUrl testUrl = composeQueryUrl(searchString);
|
||||
const DolphinQuery query = DolphinQuery::fromBalooSearchUrl(testUrl);
|
||||
|
||||
QStringList searchTerms = query.searchTerms();
|
||||
searchTerms.sort();
|
||||
|
||||
// FIXME: Current parsing bugs
|
||||
QEXPECT_FAIL("content/singleQuote", "Quotes around text are shown", Continue);
|
||||
QEXPECT_FAIL("content/doubleQuote", "Quotes around text are shown", Continue);
|
||||
|
||||
QEXPECT_FAIL("filename", "Quotes around text are shown", Continue);
|
||||
QEXPECT_FAIL("filename/singleQuote", "Quotes around text are shown", Continue);
|
||||
QEXPECT_FAIL("filename/doubleQuote", "Quotes around text are shown", Continue);
|
||||
|
||||
QEXPECT_FAIL("rating" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("rating+content" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("rating+filename" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("modified" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("modified+content" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("modified+filename" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("rating+modified" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("rating+modified+content" , "Text includes also search terms", Continue);
|
||||
QEXPECT_FAIL("rating+modified+filename", "Text includes also search terms", Continue);
|
||||
|
||||
// Check for parsed text (would be displayed on the input search bar)
|
||||
QCOMPARE(query.text(), expectedText);
|
||||
|
||||
// Check for parsed search terms (would be displayed by the facetsWidget)
|
||||
QCOMPARE(searchTerms.count(), expectedTerms.count());
|
||||
for (int i = 0; i < expectedTerms.count(); i++) {
|
||||
QCOMPARE(searchTerms.at(i), expectedTerms.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(DolphinSearchBoxTest)
|
||||
|
||||
#include "dolphinquerytest.moc"
|
Loading…
Reference in a new issue