]>
cloud.milkyroute.net Git - dolphin.git/blob - src/search/dolphinfacetswidget.cpp
1 /***************************************************************************
2 * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
3 * Copyright (C) 2019 by Ismael Asensio <isma.af@mgmail.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 * **************************************************************************/
21 #include "dolphinfacetswidget.h"
23 #include <KLocalizedString>
28 #include <QHBoxLayout>
31 #include <QToolButton>
33 DolphinFacetsWidget::DolphinFacetsWidget(QWidget
* parent
) :
35 m_typeSelector(nullptr),
36 m_dateSelector(nullptr),
37 m_ratingSelector(nullptr),
38 m_tagsSelector(nullptr)
40 m_typeSelector
= new QComboBox(this);
41 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("none")), i18nc("@item:inlistbox", "Any Type"), QString());
42 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("inode-directory")), i18nc("@item:inlistbox", "Folders") , QStringLiteral("Folder"));
43 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("text-x-generic")), i18nc("@item:inlistbox", "Documents") , QStringLiteral("Document"));
44 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("image-x-generic")), i18nc("@item:inlistbox", "Images") , QStringLiteral("Image"));
45 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("audio-x-generic")), i18nc("@item:inlistbox", "Audio Files"), QStringLiteral("Audio"));
46 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("video-x-generic")), i18nc("@item:inlistbox", "Videos") , QStringLiteral("Video"));
47 initComboBox(m_typeSelector
);
49 const QDate currentDate
= QDate::currentDate();
51 m_dateSelector
= new QComboBox(this);
52 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar")), i18nc("@item:inlistbox", "Any Date"), QDate());
53 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("go-jump-today")), i18nc("@item:inlistbox", "Today") , currentDate
);
54 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("go-jump-today")), i18nc("@item:inlistbox", "Yesterday") , currentDate
.addDays(-1));
55 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-week")), i18nc("@item:inlistbox", "This Week") , currentDate
.addDays(1 - currentDate
.dayOfWeek()));
56 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-month")), i18nc("@item:inlistbox", "This Month"), currentDate
.addDays(1 - currentDate
.day()));
57 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-year")), i18nc("@item:inlistbox", "This Year") , currentDate
.addDays(1 - currentDate
.dayOfYear()));
58 initComboBox(m_dateSelector
);
60 m_ratingSelector
= new QComboBox(this);
61 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("non-starred-symbolic")), i18nc("@item:inlistbox", "Any Rating"), 0);
62 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "1 or more"), 1);
63 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "2 or more"), 2);
64 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "3 or more"), 3);
65 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "4 or more"), 4);
66 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "Highest Rating"), 5);
67 initComboBox(m_ratingSelector
);
69 m_tagsSelector
= new QToolButton(this);
70 m_tagsSelector
->setIcon(QIcon::fromTheme(QStringLiteral("tag")));
71 m_tagsSelector
->setMenu(new QMenu(this));
72 m_tagsSelector
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
73 m_tagsSelector
->setPopupMode(QToolButton::MenuButtonPopup
);
74 m_tagsSelector
->setAutoRaise(true);
77 connect(m_tagsSelector
, &QToolButton::clicked
, m_tagsSelector
, &QToolButton::showMenu
);
78 connect(m_tagsSelector
->menu(), &QMenu::aboutToShow
, this, &DolphinFacetsWidget::updateTagsMenu
);
79 connect(&m_tagsLister
, &KCoreDirLister::itemsAdded
, this, &DolphinFacetsWidget::updateTagsMenuItems
);
82 QHBoxLayout
* topLayout
= new QHBoxLayout(this);
83 topLayout
->setContentsMargins(0, 0, 0, 0);
84 topLayout
->addWidget(m_typeSelector
);
85 topLayout
->addWidget(m_dateSelector
);
86 topLayout
->addWidget(m_ratingSelector
);
87 topLayout
->addWidget(m_tagsSelector
);
92 DolphinFacetsWidget::~DolphinFacetsWidget()
96 void DolphinFacetsWidget::changeEvent(QEvent
*event
)
98 if (event
->type() == QEvent::EnabledChange
) {
100 updateTagsSelector();
107 void DolphinFacetsWidget::resetOptions()
109 m_typeSelector
->setCurrentIndex(0);
110 m_dateSelector
->setCurrentIndex(0);
111 m_ratingSelector
->setCurrentIndex(0);
113 m_searchTags
= QStringList();
114 updateTagsSelector();
118 QString
DolphinFacetsWidget::ratingTerm() const
122 if (m_ratingSelector
->currentIndex() > 0) {
123 const int rating
= m_ratingSelector
->currentData().toInt() * 2;
124 terms
<< QStringLiteral("rating>=%1").arg(rating
);
127 if (m_dateSelector
->currentIndex() > 0) {
128 const QDate date
= m_dateSelector
->currentData().toDate();
129 terms
<< QStringLiteral("modified>=%1").arg(date
.toString(Qt::ISODate
));
132 if (!m_searchTags
.isEmpty()) {
133 for (auto const &tag
: m_searchTags
) {
134 terms
<< QStringLiteral("tag:%1").arg(tag
);
138 return terms
.join(QLatin1String(" AND "));
141 QString
DolphinFacetsWidget::facetType() const
143 return m_typeSelector
->currentData().toString();
146 bool DolphinFacetsWidget::isRatingTerm(const QString
& term
) const
148 const QStringList subTerms
= term
.split(' ', QString::SkipEmptyParts
);
150 // If term has sub terms, then sone of the sub terms are always "rating" and "modified" terms.
151 bool containsRating
= false;
152 bool containsModified
= false;
153 bool containsTag
= false;
155 foreach (const QString
& subTerm
, subTerms
) {
156 if (subTerm
.startsWith(QLatin1String("rating>="))) {
157 containsRating
= true;
158 } else if (subTerm
.startsWith(QLatin1String("modified>="))) {
159 containsModified
= true;
160 } else if (subTerm
.startsWith(QLatin1String("tag:")) ||
161 subTerm
.startsWith(QLatin1String("tag="))) {
166 return containsModified
|| containsRating
|| containsTag
;
169 void DolphinFacetsWidget::setRatingTerm(const QString
& term
)
171 // If term has sub terms, then the sub terms are always "rating" and "modified" terms.
172 // If term has no sub terms, then the term itself is either a "rating" term or a "modified"
173 // term. To avoid code duplication we add term to subTerms list, if the list is empty.
174 QStringList subTerms
= term
.split(' ', QString::SkipEmptyParts
);
176 foreach (const QString
& subTerm
, subTerms
) {
177 if (subTerm
.startsWith(QLatin1String("modified>="))) {
178 const QString value
= subTerm
.mid(10);
179 const QDate date
= QDate::fromString(value
, Qt::ISODate
);
181 } else if (subTerm
.startsWith(QLatin1String("rating>="))) {
182 const QString value
= subTerm
.mid(8);
183 const int stars
= value
.toInt() / 2;
185 } else if (subTerm
.startsWith(QLatin1String("tag:")) ||
186 subTerm
.startsWith(QLatin1String("tag="))) {
187 const QString value
= subTerm
.mid(4);
193 void DolphinFacetsWidget::setFacetType(const QString
& type
)
195 for (int index
= 0; index
<= m_typeSelector
->count(); index
++) {
196 if (type
== m_typeSelector
->itemData(index
).toString()) {
197 m_typeSelector
->setCurrentIndex(index
);
203 void DolphinFacetsWidget::setRating(const int stars
)
205 if (stars
< 0 || stars
> 5) {
208 m_ratingSelector
->setCurrentIndex(stars
);
211 void DolphinFacetsWidget::setTimespan(const QDate
& date
)
213 if (!date
.isValid()) {
216 m_dateSelector
->setCurrentIndex(0);
217 for (int index
= 1; index
<= m_dateSelector
->count(); index
++) {
218 if (date
>= m_dateSelector
->itemData(index
).toDate()) {
219 m_dateSelector
->setCurrentIndex(index
);
225 void DolphinFacetsWidget::addSearchTag(const QString
& tag
)
227 if (tag
.isEmpty() || m_searchTags
.contains(tag
)) {
230 m_searchTags
.append(tag
);
232 updateTagsSelector();
235 void DolphinFacetsWidget::removeSearchTag(const QString
& tag
)
237 if (tag
.isEmpty() || !m_searchTags
.contains(tag
)) {
240 m_searchTags
.removeAll(tag
);
241 updateTagsSelector();
244 void DolphinFacetsWidget::initComboBox(QComboBox
* combo
)
246 combo
->setFrame(false);
247 combo
->setMinimumHeight(parentWidget()->height());
248 combo
->setCurrentIndex(0);
249 connect(combo
, QOverload
<int>::of(&QComboBox::activated
), this, &DolphinFacetsWidget::facetChanged
);
252 void DolphinFacetsWidget::updateTagsSelector()
254 const bool hasListedTags
= !m_tagsSelector
->menu()->isEmpty();
255 const bool hasSelectedTags
= !m_searchTags
.isEmpty();
257 if (hasSelectedTags
) {
258 const QString tagsText
= m_searchTags
.join(i18nc("String list separator", ", "));
259 m_tagsSelector
->setText(i18ncp("@action:button %2 is a list of tags",
260 "Tag: %2", "Tags: %2",m_searchTags
.count(), tagsText
));
262 m_tagsSelector
->setText(i18nc("@action:button", "Add Tags"));
265 m_tagsSelector
->setEnabled(isEnabled() && (hasListedTags
|| hasSelectedTags
));
268 void DolphinFacetsWidget::updateTagsMenu()
270 updateTagsMenuItems({}, {});
271 m_tagsLister
.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload
);
274 void DolphinFacetsWidget::updateTagsMenuItems(const QUrl
&, const KFileItemList
& items
)
276 m_tagsSelector
->menu()->clear();
278 QStringList allTags
= QStringList(m_searchTags
);
279 for (const KFileItem
&item
: items
) {
280 allTags
.append(item
.name());
282 allTags
.sort(Qt::CaseInsensitive
);
283 allTags
.removeDuplicates();
285 for (const QString
& tagName
: qAsConst(allTags
)) {
286 QAction
* action
= m_tagsSelector
->menu()->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName
);
287 action
->setCheckable(true);
288 action
->setChecked(m_searchTags
.contains(tagName
));
290 connect(action
, &QAction::triggered
, this, [this, tagName
](bool isChecked
) {
292 addSearchTag(tagName
);
294 removeSearchTag(tagName
);
300 updateTagsSelector();