2 * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2019 Ismael Asensio <isma.af@mgmail.com>
5 * SPDX-License-Identifier: GPL-2.0-or-later
8 #include "dolphinfacetswidget.h"
10 #include <KLocalizedString>
15 #include <QHBoxLayout>
18 #include <QToolButton>
20 DolphinFacetsWidget::DolphinFacetsWidget(QWidget
* parent
) :
22 m_typeSelector(nullptr),
23 m_dateSelector(nullptr),
24 m_ratingSelector(nullptr),
25 m_tagsSelector(nullptr)
27 m_typeSelector
= new QComboBox(this);
28 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("none")), i18nc("@item:inlistbox", "Any Type"), QString());
29 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("inode-directory")), i18nc("@item:inlistbox", "Folders") , QStringLiteral("Folder"));
30 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("text-x-generic")), i18nc("@item:inlistbox", "Documents") , QStringLiteral("Document"));
31 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("image-x-generic")), i18nc("@item:inlistbox", "Images") , QStringLiteral("Image"));
32 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("audio-x-generic")), i18nc("@item:inlistbox", "Audio Files"), QStringLiteral("Audio"));
33 m_typeSelector
->addItem(QIcon::fromTheme(QStringLiteral("video-x-generic")), i18nc("@item:inlistbox", "Videos") , QStringLiteral("Video"));
34 initComboBox(m_typeSelector
);
36 const QDate currentDate
= QDate::currentDate();
38 m_dateSelector
= new QComboBox(this);
39 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar")), i18nc("@item:inlistbox", "Any Date"), QDate());
40 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("go-jump-today")), i18nc("@item:inlistbox", "Today") , currentDate
);
41 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("go-jump-today")), i18nc("@item:inlistbox", "Yesterday") , currentDate
.addDays(-1));
42 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-week")), i18nc("@item:inlistbox", "This Week") , currentDate
.addDays(1 - currentDate
.dayOfWeek()));
43 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-month")), i18nc("@item:inlistbox", "This Month"), currentDate
.addDays(1 - currentDate
.day()));
44 m_dateSelector
->addItem(QIcon::fromTheme(QStringLiteral("view-calendar-year")), i18nc("@item:inlistbox", "This Year") , currentDate
.addDays(1 - currentDate
.dayOfYear()));
45 initComboBox(m_dateSelector
);
47 m_ratingSelector
= new QComboBox(this);
48 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("non-starred-symbolic")), i18nc("@item:inlistbox", "Any Rating"), 0);
49 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "1 or more"), 1);
50 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "2 or more"), 2);
51 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "3 or more"), 3);
52 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "4 or more"), 4);
53 m_ratingSelector
->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "Highest Rating"), 5);
54 initComboBox(m_ratingSelector
);
56 m_tagsSelector
= new QToolButton(this);
57 m_tagsSelector
->setIcon(QIcon::fromTheme(QStringLiteral("tag")));
58 m_tagsSelector
->setMenu(new QMenu(this));
59 m_tagsSelector
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
60 m_tagsSelector
->setPopupMode(QToolButton::MenuButtonPopup
);
61 m_tagsSelector
->setAutoRaise(true);
64 connect(m_tagsSelector
, &QToolButton::clicked
, m_tagsSelector
, &QToolButton::showMenu
);
65 connect(m_tagsSelector
->menu(), &QMenu::aboutToShow
, this, &DolphinFacetsWidget::updateTagsMenu
);
66 connect(&m_tagsLister
, &KCoreDirLister::itemsAdded
, this, &DolphinFacetsWidget::updateTagsMenuItems
);
69 QHBoxLayout
* topLayout
= new QHBoxLayout(this);
70 topLayout
->setContentsMargins(0, 0, 0, 0);
71 topLayout
->addWidget(m_typeSelector
);
72 topLayout
->addWidget(m_dateSelector
);
73 topLayout
->addWidget(m_ratingSelector
);
74 topLayout
->addWidget(m_tagsSelector
);
79 DolphinFacetsWidget::~DolphinFacetsWidget()
83 void DolphinFacetsWidget::changeEvent(QEvent
*event
)
85 if (event
->type() == QEvent::EnabledChange
) {
94 void DolphinFacetsWidget::resetSearchTerms()
96 m_typeSelector
->setCurrentIndex(0);
97 m_dateSelector
->setCurrentIndex(0);
98 m_ratingSelector
->setCurrentIndex(0);
100 m_searchTags
= QStringList();
101 updateTagsSelector();
105 QStringList
DolphinFacetsWidget::searchTerms() const
109 if (m_ratingSelector
->currentIndex() > 0) {
110 const int rating
= m_ratingSelector
->currentData().toInt() * 2;
111 terms
<< QStringLiteral("rating>=%1").arg(rating
);
114 if (m_dateSelector
->currentIndex() > 0) {
115 const QDate date
= m_dateSelector
->currentData().toDate();
116 terms
<< QStringLiteral("modified>=%1").arg(date
.toString(Qt::ISODate
));
119 if (!m_searchTags
.isEmpty()) {
120 for (auto const &tag
: m_searchTags
) {
121 if (tag
.contains(QLatin1Char(' '))) {
122 terms
<< QStringLiteral("tag:\"%1\"").arg(tag
);
124 terms
<< QStringLiteral("tag:%1").arg(tag
);
132 QString
DolphinFacetsWidget::facetType() const
134 return m_typeSelector
->currentData().toString();
137 bool DolphinFacetsWidget::isSearchTerm(const QString
& term
) const
139 static const QLatin1String searchTokens
[] {
140 QLatin1String("modified>="),
141 QLatin1String("rating>="),
142 QLatin1String("tag:"), QLatin1String("tag=")
145 for (const auto &searchToken
: searchTokens
) {
146 if (term
.startsWith(searchToken
)) {
153 void DolphinFacetsWidget::setSearchTerm(const QString
& term
)
155 if (term
.startsWith(QLatin1String("modified>="))) {
156 const QString value
= term
.mid(10);
157 const QDate date
= QDate::fromString(value
, Qt::ISODate
);
159 } else if (term
.startsWith(QLatin1String("rating>="))) {
160 const QString value
= term
.mid(8);
161 const int stars
= value
.toInt() / 2;
163 } else if (term
.startsWith(QLatin1String("tag:")) ||
164 term
.startsWith(QLatin1String("tag="))) {
165 const QString value
= term
.mid(4);
170 void DolphinFacetsWidget::setFacetType(const QString
& type
)
172 for (int index
= 0; index
<= m_typeSelector
->count(); index
++) {
173 if (type
== m_typeSelector
->itemData(index
).toString()) {
174 m_typeSelector
->setCurrentIndex(index
);
180 void DolphinFacetsWidget::setRating(const int stars
)
182 if (stars
< 0 || stars
> 5) {
185 m_ratingSelector
->setCurrentIndex(stars
);
188 void DolphinFacetsWidget::setTimespan(const QDate
& date
)
190 if (!date
.isValid()) {
193 m_dateSelector
->setCurrentIndex(0);
194 for (int index
= 1; index
<= m_dateSelector
->count(); index
++) {
195 if (date
>= m_dateSelector
->itemData(index
).toDate()) {
196 m_dateSelector
->setCurrentIndex(index
);
202 void DolphinFacetsWidget::addSearchTag(const QString
& tag
)
204 if (tag
.isEmpty() || m_searchTags
.contains(tag
)) {
207 m_searchTags
.append(tag
);
209 updateTagsSelector();
212 void DolphinFacetsWidget::removeSearchTag(const QString
& tag
)
214 if (tag
.isEmpty() || !m_searchTags
.contains(tag
)) {
217 m_searchTags
.removeAll(tag
);
218 updateTagsSelector();
221 void DolphinFacetsWidget::initComboBox(QComboBox
* combo
)
223 combo
->setFrame(false);
224 combo
->setMinimumHeight(parentWidget()->height());
225 combo
->setCurrentIndex(0);
226 connect(combo
, QOverload
<int>::of(&QComboBox::activated
), this, &DolphinFacetsWidget::facetChanged
);
229 void DolphinFacetsWidget::updateTagsSelector()
231 const bool hasListedTags
= !m_tagsSelector
->menu()->isEmpty();
232 const bool hasSelectedTags
= !m_searchTags
.isEmpty();
234 if (hasSelectedTags
) {
235 const QString tagsText
= m_searchTags
.join(i18nc("String list separator", ", "));
236 m_tagsSelector
->setText(i18ncp("@action:button %2 is a list of tags",
237 "Tag: %2", "Tags: %2",m_searchTags
.count(), tagsText
));
239 m_tagsSelector
->setText(i18nc("@action:button", "Add Tags"));
242 m_tagsSelector
->setEnabled(isEnabled() && (hasListedTags
|| hasSelectedTags
));
245 void DolphinFacetsWidget::updateTagsMenu()
247 updateTagsMenuItems({}, {});
248 m_tagsLister
.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload
);
251 void DolphinFacetsWidget::updateTagsMenuItems(const QUrl
&, const KFileItemList
& items
)
253 m_tagsSelector
->menu()->clear();
255 QStringList allTags
= QStringList(m_searchTags
);
256 for (const KFileItem
&item
: items
) {
257 allTags
.append(item
.name());
259 allTags
.sort(Qt::CaseInsensitive
);
260 allTags
.removeDuplicates();
262 const bool onlyOneTag
= allTags
.count() == 1;
264 for (const QString
& tagName
: qAsConst(allTags
)) {
265 QAction
* action
= m_tagsSelector
->menu()->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName
);
266 action
->setCheckable(true);
267 action
->setChecked(m_searchTags
.contains(tagName
));
269 connect(action
, &QAction::triggered
, this, [this, tagName
, onlyOneTag
](bool isChecked
) {
271 addSearchTag(tagName
);
273 removeSearchTag(tagName
);
278 m_tagsSelector
->menu()->show();
283 updateTagsSelector();