]>
cloud.milkyroute.net Git - dolphin.git/blob - src/search/dolphinsearchbox.cpp
1 /***************************************************************************
2 * Copyright (C) 2010 by Peter Penz <peter.penz19@gmail.com> *
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. *
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. *
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 * **************************************************************************/
20 #include "dolphinsearchbox.h"
22 #include "dolphin_searchsettings.h"
23 #include "dolphinfacetswidget.h"
29 #include <KGlobalSettings>
31 #include <QButtonGroup>
34 #include <QFormLayout>
35 #include <QHBoxLayout>
38 #include <QScrollArea>
40 #include <QToolButton>
41 #include <QVBoxLayout>
43 #include <config-baloo.h>
45 #include <baloo/query.h>
46 #include <baloo/term.h>
47 #include <baloo/indexerconfig.h>
50 DolphinSearchBox::DolphinSearchBox(QWidget
* parent
) :
52 m_startedSearching(false),
58 m_optionsScrollArea(0),
63 m_everywhereButton(0),
64 m_facetsToggleButton(0),
72 DolphinSearchBox::~DolphinSearchBox()
77 void DolphinSearchBox::setText(const QString
& text
)
79 m_searchInput
->setText(text
);
82 QString
DolphinSearchBox::text() const
84 return m_searchInput
->text();
87 void DolphinSearchBox::setSearchPath(const KUrl
& url
)
91 QFontMetrics
metrics(m_fromHereButton
->font());
92 const int maxWidth
= metrics
.height() * 8;
94 QString location
= url
.fileName();
95 if (location
.isEmpty()) {
96 if (url
.isLocalFile()) {
97 location
= QLatin1String("/");
99 location
= url
.protocol() + QLatin1String(" - ") + url
.host();
103 const QString elidedLocation
= metrics
.elidedText(location
, Qt::ElideMiddle
, maxWidth
);
104 m_fromHereButton
->setText(i18nc("action:button", "From Here (%1)", elidedLocation
));
106 const bool showSearchFromButtons
= url
.isLocalFile() && !m_readOnly
;
107 m_separator
->setVisible(showSearchFromButtons
);
108 m_fromHereButton
->setVisible(showSearchFromButtons
);
109 m_everywhereButton
->setVisible(showSearchFromButtons
);
111 bool hasFacetsSupport
= false;
113 const Baloo::IndexerConfig searchInfo
;
114 hasFacetsSupport
= searchInfo
.fileIndexingEnabled() && searchInfo
.shouldBeIndexed(m_searchPath
.toLocalFile());
116 m_facetsWidget
->setEnabled(hasFacetsSupport
);
119 KUrl
DolphinSearchBox::searchPath() const
124 KUrl
DolphinSearchBox::urlForSearching() const
127 bool useBalooSearch
= false;
129 const Baloo::IndexerConfig searchInfo
;
130 useBalooSearch
= searchInfo
.fileIndexingEnabled() && searchInfo
.shouldBeIndexed(m_searchPath
.toLocalFile());
132 if (useBalooSearch
) {
133 url
= balooUrlForSearching();
135 url
.setProtocol("filenamesearch");
136 url
.addQueryItem("search", m_searchInput
->text());
137 if (m_contentButton
->isChecked()) {
138 url
.addQueryItem("checkContent", "yes");
142 if (m_everywhereButton
->isChecked()) {
143 // It is very unlikely, that the majority of Dolphins target users
144 // mean "the whole harddisk" instead of "my home folder" when
145 // selecting the "Everywhere" button.
146 encodedUrl
= QDir::homePath();
148 encodedUrl
= m_searchPath
.url();
150 url
.addQueryItem("url", encodedUrl
);
156 void DolphinSearchBox::selectAll()
158 m_searchInput
->selectAll();
161 void DolphinSearchBox::setReadOnly(bool readOnly
, const KUrl
& query
)
163 if (m_readOnly
!= readOnly
|| m_readOnlyQuery
!= query
) {
164 m_readOnly
= readOnly
;
165 m_readOnlyQuery
= query
;
166 applyReadOnlyState();
170 bool DolphinSearchBox::isReadOnly() const
175 void DolphinSearchBox::setActive(bool active
)
177 if (active
!= m_active
) {
186 bool DolphinSearchBox::isActive() const
191 bool DolphinSearchBox::event(QEvent
* event
)
193 if (event
->type() == QEvent::Polish
) {
196 return QWidget::event(event
);
199 void DolphinSearchBox::showEvent(QShowEvent
* event
)
201 if (!event
->spontaneous()) {
202 m_searchInput
->setFocus();
203 m_startedSearching
= false;
207 void DolphinSearchBox::keyReleaseEvent(QKeyEvent
* event
)
209 QWidget::keyReleaseEvent(event
);
210 if (event
->key() == Qt::Key_Escape
) {
211 if (m_searchInput
->text().isEmpty()) {
214 m_searchInput
->clear();
219 bool DolphinSearchBox::eventFilter(QObject
* obj
, QEvent
* event
)
221 switch (event
->type()) {
222 case QEvent::FocusIn
:
231 return QObject::eventFilter(obj
, event
);
234 void DolphinSearchBox::emitSearchRequest()
236 m_startSearchTimer
->stop();
237 m_startedSearching
= true;
238 emit
searchRequest();
241 void DolphinSearchBox::emitCloseRequest()
243 m_startSearchTimer
->stop();
244 m_startedSearching
= false;
248 void DolphinSearchBox::slotConfigurationChanged()
251 if (m_startedSearching
) {
256 void DolphinSearchBox::slotSearchTextChanged(const QString
& text
)
258 if (text
.isEmpty()) {
259 m_startSearchTimer
->stop();
261 m_startSearchTimer
->start();
263 emit
searchTextChanged(text
);
266 void DolphinSearchBox::slotReturnPressed(const QString
& text
)
269 emit
returnPressed(text
);
272 void DolphinSearchBox::slotFacetsButtonToggled()
274 const bool facetsIsVisible
= !m_facetsWidget
->isVisible();
275 m_facetsWidget
->setVisible(facetsIsVisible
);
276 updateFacetsToggleButton();
279 void DolphinSearchBox::slotFacetChanged()
281 m_startedSearching
= true;
282 m_startSearchTimer
->stop();
283 emit
searchRequest();
286 void DolphinSearchBox::initButton(QToolButton
* button
)
288 button
->installEventFilter(this);
289 button
->setAutoExclusive(true);
290 button
->setAutoRaise(true);
291 button
->setCheckable(true);
292 connect(button
, &QToolButton::clicked
, this, &DolphinSearchBox::slotConfigurationChanged
);
295 void DolphinSearchBox::loadSettings()
297 if (SearchSettings::location() == QLatin1String("Everywhere")) {
298 m_everywhereButton
->setChecked(true);
300 m_fromHereButton
->setChecked(true);
303 if (SearchSettings::what() == QLatin1String("Content")) {
304 m_contentButton
->setChecked(true);
306 m_fileNameButton
->setChecked(true);
309 m_facetsWidget
->setVisible(SearchSettings::showFacetsWidget());
312 void DolphinSearchBox::saveSettings()
314 SearchSettings::setLocation(m_fromHereButton
->isChecked() ? "FromHere" : "Everywhere");
315 SearchSettings::setWhat(m_fileNameButton
->isChecked() ? "FileName" : "Content");
316 SearchSettings::setShowFacetsWidget(m_facetsToggleButton
->isChecked());
317 SearchSettings::self()->writeConfig();
320 void DolphinSearchBox::init()
322 // Create close button
323 QToolButton
* closeButton
= new QToolButton(this);
324 closeButton
->setAutoRaise(true);
325 closeButton
->setIcon(KIcon("dialog-close"));
326 closeButton
->setToolTip(i18nc("@info:tooltip", "Quit searching"));
327 connect(closeButton
, &QToolButton::clicked
, this, &DolphinSearchBox::emitCloseRequest
);
329 // Create search label
330 m_searchLabel
= new QLabel(this);
333 m_searchInput
= new KLineEdit(this);
334 m_searchInput
->installEventFilter(this);
335 m_searchInput
->setClearButtonShown(true);
336 m_searchInput
->setFont(KGlobalSettings::generalFont());
337 setFocusProxy(m_searchInput
);
338 connect(m_searchInput
, static_cast<void(KLineEdit::*)(const QString
&)>(&KLineEdit::returnPressed
),
339 this, &DolphinSearchBox::slotReturnPressed
);
340 connect(m_searchInput
, &KLineEdit::textChanged
,
341 this, &DolphinSearchBox::slotSearchTextChanged
);
343 // Apply layout for the search input
344 QHBoxLayout
* searchInputLayout
= new QHBoxLayout();
345 searchInputLayout
->setMargin(0);
346 searchInputLayout
->addWidget(closeButton
);
347 searchInputLayout
->addWidget(m_searchLabel
);
348 searchInputLayout
->addWidget(m_searchInput
);
350 // Create "Filename" and "Content" button
351 m_fileNameButton
= new QToolButton(this);
352 m_fileNameButton
->setText(i18nc("action:button", "Filename"));
353 initButton(m_fileNameButton
);
355 m_contentButton
= new QToolButton();
356 m_contentButton
->setText(i18nc("action:button", "Content"));
357 initButton(m_contentButton
);
359 QButtonGroup
* searchWhatGroup
= new QButtonGroup(this);
360 searchWhatGroup
->addButton(m_fileNameButton
);
361 searchWhatGroup
->addButton(m_contentButton
);
363 m_separator
= new KSeparator(Qt::Vertical
, this);
365 // Create "From Here" and "Everywhere"button
366 m_fromHereButton
= new QToolButton(this);
367 m_fromHereButton
->setText(i18nc("action:button", "From Here"));
368 initButton(m_fromHereButton
);
370 m_everywhereButton
= new QToolButton(this);
371 m_everywhereButton
->setText(i18nc("action:button", "Everywhere"));
372 initButton(m_everywhereButton
);
374 QButtonGroup
* searchLocationGroup
= new QButtonGroup(this);
375 searchLocationGroup
->addButton(m_fromHereButton
);
376 searchLocationGroup
->addButton(m_everywhereButton
);
378 // Create "Facets" widgets
379 m_facetsToggleButton
= new QToolButton(this);
380 m_facetsToggleButton
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
381 initButton(m_facetsToggleButton
);
382 connect(m_facetsToggleButton
, &QToolButton::clicked
, this, &DolphinSearchBox::slotFacetsButtonToggled
);
384 m_facetsWidget
= new DolphinFacetsWidget(this);
385 m_facetsWidget
->installEventFilter(this);
386 m_facetsWidget
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Maximum
);
387 connect(m_facetsWidget
, &DolphinFacetsWidget::facetChanged
, this, &DolphinSearchBox::slotFacetChanged
);
389 // Apply layout for the options
390 QHBoxLayout
* optionsLayout
= new QHBoxLayout();
391 optionsLayout
->setMargin(0);
392 optionsLayout
->addWidget(m_fileNameButton
);
393 optionsLayout
->addWidget(m_contentButton
);
394 optionsLayout
->addWidget(m_separator
);
395 optionsLayout
->addWidget(m_fromHereButton
);
396 optionsLayout
->addWidget(m_everywhereButton
);
397 optionsLayout
->addStretch(1);
398 optionsLayout
->addWidget(m_facetsToggleButton
);
400 // Put the options into a QScrollArea. This prevents increasing the view width
401 // in case that not enough width for the options is available.
402 QWidget
* optionsContainer
= new QWidget(this);
403 optionsContainer
->setLayout(optionsLayout
);
405 m_optionsScrollArea
= new QScrollArea(this);
406 m_optionsScrollArea
->setFrameShape(QFrame::NoFrame
);
407 m_optionsScrollArea
->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
408 m_optionsScrollArea
->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
409 m_optionsScrollArea
->setMaximumHeight(optionsContainer
->sizeHint().height());
410 m_optionsScrollArea
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Fixed
);
411 m_optionsScrollArea
->setWidget(optionsContainer
);
412 m_optionsScrollArea
->setWidgetResizable(true);
414 m_topLayout
= new QVBoxLayout(this);
415 m_topLayout
->setMargin(0);
416 m_topLayout
->addLayout(searchInputLayout
);
417 m_topLayout
->addWidget(m_optionsScrollArea
);
418 m_topLayout
->addWidget(m_facetsWidget
);
422 // The searching should be started automatically after the user did not change
423 // the text within one second
424 m_startSearchTimer
= new QTimer(this);
425 m_startSearchTimer
->setSingleShot(true);
426 m_startSearchTimer
->setInterval(1000);
427 connect(m_startSearchTimer
, &QTimer::timeout
, this, &DolphinSearchBox::emitSearchRequest
);
429 updateFacetsToggleButton();
430 applyReadOnlyState();
433 KUrl
DolphinSearchBox::balooUrlForSearching() const
436 const QString text
= m_searchInput
->text();
439 query
.addType("File");
440 query
.addTypes(m_facetsWidget
->facetTypes());
442 Baloo::Term
term(Baloo::Term::And
);
444 Baloo::Term ratingTerm
= m_facetsWidget
->ratingTerm();
445 if (ratingTerm
.isValid()) {
446 term
.addSubTerm(ratingTerm
);
449 if (m_contentButton
->isChecked()) {
450 query
.setSearchString(text
);
452 term
.addSubTerm(Baloo::Term("filename", text
));
455 if (m_fromHereButton
->isChecked()) {
456 query
.addCustomOption("includeFolder", m_searchPath
.toLocalFile());
459 return query
.toSearchUrl(i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.",
460 "Query Results from '%1'", text
));
466 void DolphinSearchBox::applyReadOnlyState()
470 m_searchLabel
->setText(Baloo::Query::titleFromQueryUrl(m_readOnlyQuery
));
475 m_searchLabel
->setText(i18nc("@label:textbox", "Find:"));
478 m_searchInput
->setVisible(!m_readOnly
);
479 m_optionsScrollArea
->setVisible(!m_readOnly
);
482 m_facetsWidget
->hide();
484 m_facetsWidget
->setVisible(SearchSettings::showFacetsWidget());
488 void DolphinSearchBox::updateFacetsToggleButton()
490 const bool facetsIsVisible
= SearchSettings::showFacetsWidget();
491 m_facetsToggleButton
->setChecked(facetsIsVisible
? true : false);
492 m_facetsToggleButton
->setIcon(KIcon(facetsIsVisible
? "arrow-up-double" : "arrow-down-double"));
493 m_facetsToggleButton
->setText(facetsIsVisible
? i18nc("action:button", "Fewer Options") : i18nc("action:button", "More Options"));
496 #include "dolphinsearchbox.moc"