1 /***************************************************************************
2 * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
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 "dolphinsearchoptionsconfigurator.h"
22 #include "dolphin_searchsettings.h"
23 #include <settings/dolphinsettings.h>
25 #define DISABLE_NEPOMUK_LEGACY
26 #include <nepomuk/andterm.h>
27 #include <nepomuk/filequery.h>
28 #include <nepomuk/orterm.h>
29 #include <nepomuk/queryparser.h>
30 #include <nepomuk/resourcetypeterm.h>
31 #include <nepomuk/term.h>
35 #include <kcombobox.h>
37 #include <kfileplacesmodel.h>
39 #include <klineedit.h>
41 #include <kseparator.h>
43 #include "searchcriterionselector.h"
45 #include <QButtonGroup>
46 #include <QHBoxLayout>
48 #include <QPushButton>
50 #include <QVBoxLayout>
54 const char* settingsName
;
58 // Contains the settings names and translated texts
59 // for each item of the location-combo-box.
60 static const SettingsItem g_locationItems
[] = {
61 {"Everywhere", I18N_NOOP2("@label", "Everywhere")},
62 {"From Here", I18N_NOOP2("@label", "From Here")}
65 // Contains the settings names and translated texts
66 // for each item of the what-combobox.
67 static const SettingsItem g_whatItems
[] = {
68 {"All", I18N_NOOP2("@label", "All")},
69 {"Images", I18N_NOOP2("@label", "Images")},
70 {"Text", I18N_NOOP2("@label", "Text")},
71 {"Filenames", I18N_NOOP2("@label", "Filenames")}
76 const char* settingsName
;
77 SearchCriterionSelector::Type type
;
80 // Contains the settings names for type
81 // of availabe search criterion.
82 static const CriterionItem g_criterionItems
[] = {
83 {"Date", SearchCriterionSelector::Date
},
84 {"Size", SearchCriterionSelector::Size
},
85 {"Tag", SearchCriterionSelector::Tag
},
86 {"Raging", SearchCriterionSelector::Rating
}
89 DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget
* parent
) :
95 m_addSelectorButton(0),
100 m_customSearchQuery()
102 m_vBoxLayout
= new QVBoxLayout(this);
104 // add "search" configuration
105 QLabel
* searchLabel
= new QLabel(i18nc("@label", "Search:"));
107 m_locationBox
= new KComboBox(this);
108 for (unsigned int i
= 0; i
< sizeof(g_locationItems
) / sizeof(SettingsItem
); ++i
) {
109 m_locationBox
->addItem(g_locationItems
[i
].text
);
112 // add "what" configuration
113 QLabel
* whatLabel
= new QLabel(i18nc("@label", "What:"));
115 m_whatBox
= new KComboBox(this);
116 for (unsigned int i
= 0; i
< sizeof(g_whatItems
) / sizeof(SettingsItem
); ++i
) {
117 m_whatBox
->addItem(g_whatItems
[i
].text
);
119 connect(m_whatBox
, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
121 // add "Add selector" button
122 m_addSelectorButton
= new QPushButton(this);
123 m_addSelectorButton
->setIcon(KIcon("list-add"));
124 m_addSelectorButton
->setToolTip(i18nc("@info", "Add search option"));
125 m_addSelectorButton
->setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
126 connect(m_addSelectorButton
, SIGNAL(clicked()), this, SLOT(slotAddSelectorButtonClicked()));
128 // add button "Search"
129 m_searchButton
= new QPushButton(this);
130 m_searchButton
->setIcon(KIcon("edit-find"));
131 m_searchButton
->setText(i18nc("@action:button", "Search"));
132 m_searchButton
->setToolTip(i18nc("@info", "Start searching"));
133 m_searchButton
->setEnabled(false);
134 connect(m_searchButton
, SIGNAL(clicked()), this, SIGNAL(searchOptionsChanged()));
137 m_saveButton
= new QPushButton(this);
138 m_saveButton
->setIcon(KIcon("document-save"));
139 m_saveButton
->setText(i18nc("@action:button", "Save"));
140 m_saveButton
->setToolTip(i18nc("@info", "Save search options"));
141 m_saveButton
->setEnabled(false);
142 connect(m_saveButton
, SIGNAL(clicked()), this, SLOT(saveQuery()));
144 // add button "Close"
145 QPushButton
* closeButton
= new QPushButton(this);
146 closeButton
->setIcon(KIcon("dialog-close"));
147 closeButton
->setText(i18nc("@action:button", "Close"));
148 closeButton
->setToolTip(i18nc("@info", "Close search options"));
149 connect(closeButton
, SIGNAL(clicked()), this, SLOT(hide()));
151 QHBoxLayout
* topLineLayout
= new QHBoxLayout();
152 topLineLayout
->addWidget(m_addSelectorButton
);
153 topLineLayout
->addWidget(searchLabel
);
154 topLineLayout
->addWidget(m_locationBox
);
155 topLineLayout
->addWidget(whatLabel
);
156 topLineLayout
->addWidget(m_whatBox
);
157 topLineLayout
->addWidget(new QWidget(this), 1); // filler
158 topLineLayout
->addWidget(m_searchButton
);
159 topLineLayout
->addWidget(m_saveButton
);
160 topLineLayout
->addWidget(closeButton
);
162 m_vBoxLayout
->addWidget(new KSeparator(this));
163 m_vBoxLayout
->addLayout(topLineLayout
);
164 m_vBoxLayout
->addWidget(new KSeparator(this));
167 DolphinSearchOptionsConfigurator::~DolphinSearchOptionsConfigurator()
169 // store the UI configuration
170 const int locationIndex
= m_locationBox
->currentIndex();
171 SearchSettings::setLocation(g_locationItems
[locationIndex
].settingsName
);
173 const int whatIndex
= m_whatBox
->currentIndex();
174 SearchSettings::setWhat(g_whatItems
[whatIndex
].settingsName
);
176 QString criteriaString
;
177 foreach(const SearchCriterionSelector
* criterion
, m_criteria
) {
178 if (!criteriaString
.isEmpty()) {
179 criteriaString
+= ',';
181 const int index
= static_cast<int>(criterion
->type());
182 criteriaString
+= g_criterionItems
[index
].settingsName
;
184 SearchSettings::setCriteria(criteriaString
);
186 SearchSettings::self()->writeConfig();
189 QString
DolphinSearchOptionsConfigurator::customSearchQuery() const
191 return m_customSearchQuery
;
195 KUrl
DolphinSearchOptionsConfigurator::directory() const
200 KUrl
DolphinSearchOptionsConfigurator::nepomukSearchUrl() const
202 const Nepomuk::Query::Query query
= nepomukQuery();
203 return query
.isValid() ? query
.toSearchUrl() : KUrl();
206 void DolphinSearchOptionsConfigurator::setCustomSearchQuery(const QString
& searchQuery
)
208 m_customSearchQuery
= searchQuery
.simplified();
212 void DolphinSearchOptionsConfigurator::setDirectory(const KUrl
& dir
)
214 if (dir
.protocol() != QString::fromLatin1("nepomuksearch")) {
219 void DolphinSearchOptionsConfigurator::showEvent(QShowEvent
* event
)
221 if (!event
->spontaneous() && !m_initialized
) {
222 // restore the UI layout of the last session
223 const QString location
= SearchSettings::location();
224 for (unsigned int i
= 0; i
< sizeof(g_locationItems
) / sizeof(SettingsItem
); ++i
) {
225 if (g_locationItems
[i
].settingsName
== location
) {
226 m_locationBox
->setCurrentIndex(i
);
231 const QString what
= SearchSettings::what();
232 for (unsigned int i
= 0; i
< sizeof(g_whatItems
) / sizeof(SettingsItem
); ++i
) {
233 if (g_whatItems
[i
].settingsName
== what
) {
234 m_whatBox
->setCurrentIndex(i
);
239 const QString criteria
= SearchSettings::criteria();
240 QStringList criteriaList
= criteria
.split(',');
241 foreach (const QString
& criterionName
, criteriaList
) {
242 for (unsigned int i
= 0; i
< sizeof(g_criterionItems
) / sizeof(CriterionItem
); ++i
) {
243 if (g_criterionItems
[i
].settingsName
== criterionName
) {
244 const SearchCriterionSelector::Type type
= g_criterionItems
[i
].type
;
245 addCriterion(new SearchCriterionSelector(type
, this));
251 m_initialized
= true;
253 QWidget::showEvent(event
);
256 void DolphinSearchOptionsConfigurator::slotAddSelectorButtonClicked()
258 SearchCriterionSelector
* selector
= new SearchCriterionSelector(SearchCriterionSelector::Date
, this);
259 addCriterion(selector
);
262 void DolphinSearchOptionsConfigurator::removeCriterion()
264 SearchCriterionSelector
* criterion
= qobject_cast
<SearchCriterionSelector
*>(sender());
265 Q_ASSERT(criterion
!= 0);
266 m_vBoxLayout
->removeWidget(criterion
);
268 const int index
= m_criteria
.indexOf(criterion
);
269 m_criteria
.removeAt(index
);
271 criterion
->deleteLater();
276 void DolphinSearchOptionsConfigurator::saveQuery()
278 // TODO: provide a custom dialog class for KDE 4.5, which
279 // enables/disables the OK button depend on whether a text
281 QPointer
<KDialog
> dialog
= new KDialog(0, Qt::Dialog
);
283 QWidget
* container
= new QWidget(dialog
);
285 QLabel
* label
= new QLabel(i18nc("@label", "Name:"), container
);
286 KLineEdit
* lineEdit
= new KLineEdit(container
);
287 lineEdit
->setMinimumWidth(250);
289 QHBoxLayout
* layout
= new QHBoxLayout(container
);
290 layout
->addWidget(label
, Qt::AlignRight
);
291 layout
->addWidget(lineEdit
);
293 dialog
->setMainWidget(container
);
294 dialog
->setCaption(i18nc("@title:window", "Save Search Options"));
295 dialog
->setButtons(KDialog::Ok
| KDialog::Cancel
);
296 dialog
->setDefaultButton(KDialog::Ok
);
297 dialog
->setButtonText(KDialog::Ok
, i18nc("@action:button", "Save"));
299 KConfigGroup
dialogConfig(KSharedConfig::openConfig("dolphinrc"),
300 "SaveSearchOptionsDialog");
301 dialog
->restoreDialogSize(dialogConfig
);
302 if ((dialog
->exec() == QDialog::Accepted
) && !lineEdit
->text().isEmpty()) {
303 KFilePlacesModel
* model
= DolphinSettings::instance().placesModel();
304 model
->addPlace(lineEdit
->text(), nepomukSearchUrl());
309 void DolphinSearchOptionsConfigurator::updateButtons()
311 const bool enable
= nepomukQuery().isValid();
312 m_searchButton
->setEnabled(enable
);
313 m_saveButton
->setEnabled(enable
);
315 const int selectors
= m_vBoxLayout
->count() - 1;
316 m_addSelectorButton
->setEnabled(selectors
< 10);
319 void DolphinSearchOptionsConfigurator::addCriterion(SearchCriterionSelector
* criterion
)
321 connect(criterion
, SIGNAL(removeCriterion()), this, SLOT(removeCriterion()));
322 connect(criterion
, SIGNAL(criterionChanged()), this, SLOT(updateButtons()));
324 // insert the new selector before the KSeparator at the bottom
325 const int index
= m_vBoxLayout
->count() - 1;
326 m_vBoxLayout
->insertWidget(index
, criterion
);
329 m_criteria
.append(criterion
);
332 Nepomuk::Query::Query
DolphinSearchOptionsConfigurator::nepomukQuery() const
334 Nepomuk::Query::AndTerm andTerm
;
336 // add search criterion terms
337 foreach (const SearchCriterionSelector
* criterion
, m_criteria
) {
338 const Nepomuk::Query::Term term
= criterion
->queryTerm();
339 andTerm
.addSubTerm(term
);
342 // add custom query term from the searchbar
343 const Nepomuk::Query::Query customQuery
= Nepomuk::Query::QueryParser::parseQuery(m_customSearchQuery
);
344 if (customQuery
.isValid()) {
345 andTerm
.addSubTerm(customQuery
.term());
348 // filter result by the "What" filter
349 switch (m_whatBox
->currentIndex()) {
352 const Nepomuk::Query::ResourceTypeTerm
image(Nepomuk::Vocabulary::NFO::Image());
353 andTerm
.addSubTerm(image
);
358 const Nepomuk::Query::ResourceTypeTerm
textDocument(Nepomuk::Vocabulary::NFO::TextDocument());
359 andTerm
.addSubTerm(textDocument
);
365 Nepomuk::Query::FileQuery fileQuery
;
366 if ((m_locationBox
->currentIndex() == 1) && m_directory
.isValid()) {
367 // "From Here" is selected as location filter
368 fileQuery
.addIncludeFolder(m_directory
);
370 fileQuery
.setTerm(andTerm
);
374 #include "dolphinsearchoptionsconfigurator.moc"