* show only a minimized set of search options per default

* remember the search options when closing Dolphin, so that the user can adjust his "default search template"

svn path=/trunk/KDE/kdebase/apps/; revision=1052499
This commit is contained in:
Peter Penz 2009-11-21 22:08:59 +00:00
parent 42372dc3b5
commit 35ba6eb132
8 changed files with 210 additions and 84 deletions

View file

@ -157,11 +157,13 @@ set(dolphin_SRCS
statusbar/statusbarspaceinfo.cpp statusbar/statusbarspaceinfo.cpp
statusbar/statusbarmessagelabel.cpp statusbar/statusbarmessagelabel.cpp
zoomlevelinfo.cpp zoomlevelinfo.cpp
) )
kde4_add_kcfg_files(dolphin_SRCS kde4_add_kcfg_files(dolphin_SRCS
panels/folders/dolphin_folderspanelsettings.kcfgc panels/folders/dolphin_folderspanelsettings.kcfgc
panels/information/dolphin_informationpanelsettings.kcfgc) panels/information/dolphin_informationpanelsettings.kcfgc
search/dolphin_searchsettings.kcfgc
)
if(Nepomuk_FOUND) if(Nepomuk_FOUND)
set(dolphin_SRCS set(dolphin_SRCS

View file

@ -1010,18 +1010,8 @@ void DolphinMainWindow::slotTestCanDecode(const QDragMoveEvent* event, bool& can
void DolphinMainWindow::searchItems() void DolphinMainWindow::searchItems()
{ {
#ifdef HAVE_NEPOMUK #ifdef HAVE_NEPOMUK
const QString searchOptions = m_searchOptionsConfigurator->options(); const KUrl nepomukUrl = m_searchOptionsConfigurator->nepomukUrl();
m_activeViewContainer->setUrl(nepomukUrl);
QString searchString = m_searchBox->text();
if (!searchString.isEmpty() && !searchOptions.isEmpty()) {
searchString += ' ' + searchOptions;
} else if (!searchOptions.isEmpty()) {
searchString += searchOptions;
}
if (!searchString.isEmpty()) {
m_activeViewContainer->setUrl(KUrl("nepomuksearch:/" + searchString));
}
#endif #endif
} }
@ -1081,7 +1071,7 @@ void DolphinMainWindow::init()
#ifdef HAVE_NEPOMUK #ifdef HAVE_NEPOMUK
m_searchOptionsConfigurator = new DolphinSearchOptionsConfigurator(this); m_searchOptionsConfigurator = new DolphinSearchOptionsConfigurator(this);
m_searchOptionsConfigurator->hide(); m_searchOptionsConfigurator->hide();
connect(m_searchOptionsConfigurator, SIGNAL(searchOptionsChanged(QString)), connect(m_searchOptionsConfigurator, SIGNAL(searchOptionsChanged()),
this, SLOT(searchItems())); this, SLOT(searchItems()));
#endif #endif
@ -1127,6 +1117,8 @@ void DolphinMainWindow::init()
m_searchBox->show(); m_searchBox->show();
connect(m_searchBox, SIGNAL(requestSearchOptions()), connect(m_searchBox, SIGNAL(requestSearchOptions()),
this, SLOT(showSearchOptions())); this, SLOT(showSearchOptions()));
connect(m_searchBox, SIGNAL(searchTextChanged(QString)),
m_searchOptionsConfigurator, SLOT(setCustomSearchQuery(QString)));
stateChanged("new_file"); stateChanged("new_file");

View file

@ -250,6 +250,8 @@ DolphinSearchBox::DolphinSearchBox(QWidget* parent) :
hLayout->addWidget(m_searchInput); hLayout->addWidget(m_searchInput);
connect(m_searchInput, SIGNAL(returnPressed()), connect(m_searchInput, SIGNAL(returnPressed()),
this, SLOT(emitSearchSignal())); this, SLOT(emitSearchSignal()));
connect(m_searchInput, SIGNAL(textChanged(QString)),
this, SIGNAL(searchTextChanged(QString)));
} }
DolphinSearchBox::~DolphinSearchBox() DolphinSearchBox::~DolphinSearchBox()

View file

@ -87,6 +87,12 @@ signals:
*/ */
void search(const QString& text); void search(const QString& text);
/**
* Is emitted when the user has changed a character of
* the text that should be used as input for searching.
*/
void searchTextChanged(const QString& text);
/** /**
* Is emitted if the search box gets the focus and * Is emitted if the search box gets the focus and
* requests the need for a UI that allows to adjust * requests the need for a UI that allows to adjust

View file

@ -19,6 +19,7 @@
#include "dolphinsearchoptionsconfigurator.h" #include "dolphinsearchoptionsconfigurator.h"
#include "dolphin_searchsettings.h"
#include "searchcriterionselector.h" #include "searchcriterionselector.h"
#include <kcombobox.h> #include <kcombobox.h>
@ -35,32 +36,72 @@
#include <QShowEvent> #include <QShowEvent>
#include <QVBoxLayout> #include <QVBoxLayout>
struct SettingsItem
{
const char* settingsName;
const char* text;
};
// Contains the settings names and translated texts
// for each item of the location-combo-box.
static const SettingsItem g_locationItems[] = {
{"Everywhere", I18N_NOOP2("@label", "Everywhere")},
{"From Here", I18N_NOOP2("@label", "From Here")}
};
// Contains the settings names and translated texts
// for each item of the what-combobox.
static const SettingsItem g_whatItems[] = {
{"All", I18N_NOOP2("@label", "All")},
{"Images", I18N_NOOP2("@label", "Images")},
{"Text", I18N_NOOP2("@label", "Text")},
{"Filenames", I18N_NOOP2("@label", "Filenames")}
};
struct CriterionItem
{
const char* settingsName;
SearchCriterionSelector::Type type;
};
// Contains the settings names for type
// of availabe search criterion.
static const CriterionItem g_criterionItems[] = {
{"Date", SearchCriterionSelector::Date},
{"Size", SearchCriterionSelector::Size},
{"Tag", SearchCriterionSelector::Tag},
{"Raging", SearchCriterionSelector::Rating}
};
DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* parent) : DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* parent) :
QWidget(parent), QWidget(parent),
m_initialized(false), m_initialized(false),
m_searchFromBox(0), m_locationBox(0),
m_searchWhatBox(0), m_whatBox(0),
m_addSelectorButton(0), m_addSelectorButton(0),
m_searchButton(0),
m_saveButton(0),
m_vBoxLayout(0), m_vBoxLayout(0),
m_criterions() m_criterions(),
m_customSearchQuery()
{ {
m_vBoxLayout = new QVBoxLayout(this); m_vBoxLayout = new QVBoxLayout(this);
// add "search" configuration // add "search" configuration
QLabel* searchLabel = new QLabel(i18nc("@label", "Search:")); QLabel* searchLabel = new QLabel(i18nc("@label", "Search:"));
m_searchFromBox = new KComboBox(this); m_locationBox = new KComboBox(this);
m_searchFromBox->addItem(i18nc("@label", "Everywhere")); for (unsigned int i = 0; i < sizeof(g_locationItems) / sizeof(SettingsItem); ++i) {
m_searchFromBox->addItem(i18nc("@label", "From Here")); m_locationBox->addItem(g_locationItems[i].text);
}
// add "what" configuration // add "what" configuration
QLabel* whatLabel = new QLabel(i18nc("@label", "What:")); QLabel* whatLabel = new QLabel(i18nc("@label", "What:"));
m_searchWhatBox = new KComboBox(this); m_whatBox = new KComboBox(this);
m_searchWhatBox->addItem(i18nc("@label", "All")); for (unsigned int i = 0; i < sizeof(g_whatItems) / sizeof(SettingsItem); ++i) {
m_searchWhatBox->addItem(i18nc("@label", "Images")); m_whatBox->addItem(g_whatItems[i].text);
m_searchWhatBox->addItem(i18nc("@label", "Text")); }
m_searchWhatBox->addItem(i18nc("@label", "Filenames"));
// add "Add selector" button // add "Add selector" button
m_addSelectorButton = new QPushButton(this); m_addSelectorButton = new QPushButton(this);
@ -70,18 +111,20 @@ DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* pare
connect(m_addSelectorButton, SIGNAL(clicked()), this, SLOT(slotAddSelectorButtonClicked())); connect(m_addSelectorButton, SIGNAL(clicked()), this, SLOT(slotAddSelectorButtonClicked()));
// add button "Search" // add button "Search"
QPushButton* searchButton = new QPushButton(this); m_searchButton = new QPushButton(this);
searchButton->setIcon(KIcon("edit-find")); m_searchButton->setIcon(KIcon("edit-find"));
searchButton->setText(i18nc("@action:button", "Search")); m_searchButton->setText(i18nc("@action:button", "Search"));
searchButton->setToolTip(i18nc("@info", "Start searching")); m_searchButton->setToolTip(i18nc("@info", "Start searching"));
connect(searchButton, SIGNAL(clicked()), this, SLOT(emitSearchOptionsChanged())); m_searchButton->setEnabled(false);
connect(m_searchButton, SIGNAL(clicked()), this, SIGNAL(searchOptionsChanged()));
// add button "Save" // add button "Save"
QPushButton* saveButton = new QPushButton(this); m_saveButton = new QPushButton(this);
saveButton->setIcon(KIcon("document-save")); m_saveButton->setIcon(KIcon("document-save"));
saveButton->setText(i18nc("@action:button", "Save")); m_saveButton->setText(i18nc("@action:button", "Save"));
saveButton->setToolTip(i18nc("@info", "Save search options")); m_saveButton->setToolTip(i18nc("@info", "Save search options"));
connect(saveButton, SIGNAL(clicked()), this, SLOT(saveQuery())); m_saveButton->setEnabled(false);
connect(m_saveButton, SIGNAL(clicked()), this, SLOT(saveQuery()));
// add button "Close" // add button "Close"
QPushButton* closeButton = new QPushButton(this); QPushButton* closeButton = new QPushButton(this);
@ -90,31 +133,45 @@ DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* pare
closeButton->setToolTip(i18nc("@info", "Close search options")); closeButton->setToolTip(i18nc("@info", "Close search options"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(hide())); connect(closeButton, SIGNAL(clicked()), this, SLOT(hide()));
QHBoxLayout* firstLineLayout = new QHBoxLayout(); QHBoxLayout* topLineLayout = new QHBoxLayout();
firstLineLayout->addWidget(searchLabel); topLineLayout->addWidget(m_addSelectorButton);
firstLineLayout->addWidget(m_searchFromBox); topLineLayout->addWidget(searchLabel);
firstLineLayout->addWidget(whatLabel); topLineLayout->addWidget(m_locationBox);
firstLineLayout->addWidget(m_searchWhatBox); topLineLayout->addWidget(whatLabel);
firstLineLayout->addWidget(new QWidget(this), 1); // filler topLineLayout->addWidget(m_whatBox);
topLineLayout->addWidget(new QWidget(this), 1); // filler
QHBoxLayout* lastLineLayout = new QHBoxLayout(); topLineLayout->addWidget(m_searchButton);
lastLineLayout->addWidget(m_addSelectorButton); topLineLayout->addWidget(m_saveButton);
lastLineLayout->addWidget(new QWidget(this), 1); // filler topLineLayout->addWidget(closeButton);
lastLineLayout->addWidget(searchButton);
lastLineLayout->addWidget(saveButton);
lastLineLayout->addWidget(closeButton);
m_vBoxLayout->addWidget(new KSeparator(this)); m_vBoxLayout->addWidget(new KSeparator(this));
m_vBoxLayout->addLayout(firstLineLayout); m_vBoxLayout->addLayout(topLineLayout);
m_vBoxLayout->addLayout(lastLineLayout);
m_vBoxLayout->addWidget(new KSeparator(this)); m_vBoxLayout->addWidget(new KSeparator(this));
} }
DolphinSearchOptionsConfigurator::~DolphinSearchOptionsConfigurator() DolphinSearchOptionsConfigurator::~DolphinSearchOptionsConfigurator()
{ {
// store the UI configuration
const int locationIndex = m_locationBox->currentIndex();
SearchSettings::setLocation(g_locationItems[locationIndex].settingsName);
const int whatIndex = m_whatBox->currentIndex();
SearchSettings::setWhat(g_whatItems[whatIndex].settingsName);
QString criterionsString;
foreach(const SearchCriterionSelector* criterion, m_criterions) {
if (!criterionsString.isEmpty()) {
criterionsString += ',';
}
const int index = static_cast<int>(criterion->type());
criterionsString += g_criterionItems[index].settingsName;
}
SearchSettings::setCriterions(criterionsString);
SearchSettings::self()->writeConfig();
} }
QString DolphinSearchOptionsConfigurator::options() const KUrl DolphinSearchOptionsConfigurator::nepomukUrl() const
{ {
QString searchOptions; QString searchOptions;
foreach (const SearchCriterionSelector* criterion, m_criterions) { foreach (const SearchCriterionSelector* criterion, m_criterions) {
@ -126,25 +183,58 @@ QString DolphinSearchOptionsConfigurator::options() const
searchOptions += criterionString; searchOptions += criterionString;
} }
} }
return searchOptions;
QString searchString = m_customSearchQuery;
if (!searchString.isEmpty() && !searchOptions.isEmpty()) {
searchString += ' ' + searchOptions;
} else if (!searchOptions.isEmpty()) {
searchString += searchOptions;
}
searchString.insert(0, QLatin1String("nepomuksearch:/"));
return KUrl(searchString);
}
void DolphinSearchOptionsConfigurator::setCustomSearchQuery(const QString& searchQuery)
{
m_customSearchQuery = searchQuery.simplified();
const bool enabled = hasSearchParameters();
m_searchButton->setEnabled(enabled);
m_saveButton->setEnabled(enabled);
} }
void DolphinSearchOptionsConfigurator::showEvent(QShowEvent* event) void DolphinSearchOptionsConfigurator::showEvent(QShowEvent* event)
{ {
if (!event->spontaneous() && !m_initialized) { if (!event->spontaneous() && !m_initialized) {
// add default search criterions // restore the UI layout of the last session
SearchCriterionSelector* dateCriterion = new SearchCriterionSelector(SearchCriterionSelector::Date, this); const QString location = SearchSettings::location();
SearchCriterionSelector* sizeCriterion = new SearchCriterionSelector(SearchCriterionSelector::Size, this); for (unsigned int i = 0; i < sizeof(g_locationItems) / sizeof(SettingsItem); ++i) {
SearchCriterionSelector* tagCriterion = new SearchCriterionSelector(SearchCriterionSelector::Tag, this); if (g_locationItems[i].settingsName == location) {
m_locationBox->setCurrentIndex(i);
break;
}
}
// Add the items in the same order as available in the description combo (verified by Q_ASSERTs). This const QString what = SearchSettings::what();
// is not mandatory from an implementation point of view, but preferable from a usability point of view. for (unsigned int i = 0; i < sizeof(g_whatItems) / sizeof(SettingsItem); ++i) {
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Date) == 0); if (g_whatItems[i].settingsName == what) {
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Size) == 1); m_whatBox->setCurrentIndex(i);
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Tag) == 2); break;
addCriterion(dateCriterion); }
addCriterion(sizeCriterion); }
addCriterion(tagCriterion);
const QString criterions = SearchSettings::criterions();
QStringList criterionsList = criterions.split(',');
foreach (const QString& criterionName, criterionsList) {
for (unsigned int i = 0; i < sizeof(g_criterionItems) / sizeof(CriterionItem); ++i) {
if (g_criterionItems[i].settingsName == criterionName) {
const SearchCriterionSelector::Type type = g_criterionItems[i].type;
addCriterion(new SearchCriterionSelector(type, this));
break;
}
}
}
m_initialized = true; m_initialized = true;
} }
@ -153,13 +243,15 @@ void DolphinSearchOptionsConfigurator::showEvent(QShowEvent* event)
void DolphinSearchOptionsConfigurator::slotAddSelectorButtonClicked() void DolphinSearchOptionsConfigurator::slotAddSelectorButtonClicked()
{ {
SearchCriterionSelector* selector = new SearchCriterionSelector(SearchCriterionSelector::Tag, this); SearchCriterionSelector* selector = new SearchCriterionSelector(SearchCriterionSelector::Date, this);
addCriterion(selector); addCriterion(selector);
} }
void DolphinSearchOptionsConfigurator::emitSearchOptionsChanged() void DolphinSearchOptionsConfigurator::slotCriterionChanged()
{ {
emit searchOptionsChanged(options()); const bool enabled = hasSearchParameters();
m_searchButton->setEnabled(enabled);
m_saveButton->setEnabled(enabled);
} }
void DolphinSearchOptionsConfigurator::removeCriterion() void DolphinSearchOptionsConfigurator::removeCriterion()
@ -211,18 +303,24 @@ void DolphinSearchOptionsConfigurator::saveQuery()
void DolphinSearchOptionsConfigurator::addCriterion(SearchCriterionSelector* criterion) void DolphinSearchOptionsConfigurator::addCriterion(SearchCriterionSelector* criterion)
{ {
connect(criterion, SIGNAL(removeCriterion()), this, SLOT(removeCriterion())); connect(criterion, SIGNAL(removeCriterion()), this, SLOT(removeCriterion()));
// TODO: It is unclear yet whether changing a criterion should also result in triggering connect(criterion, SIGNAL(criterionChanged()), this, SLOT(slotCriterionChanged()));
// a searchOptionsChanged() signal. This mainly depends on the performance achievable with
// Nepomuk. Currently the searchOptionsChanged() signal is only emitted when the search-button
// has been triggered by the user.
// connect(criterion, SIGNAL(criterionChanged()), this, SLOT(emitSearchOptionsChanged()));
// insert the new selector before the lastLineLayout and the KSeparator at the bottom // insert the new selector before the KSeparator at the bottom
const int index = m_vBoxLayout->count() - 2; const int index = m_vBoxLayout->count() - 1;
m_vBoxLayout->insertWidget(index, criterion); m_vBoxLayout->insertWidget(index, criterion);
updateSelectorButton(); updateSelectorButton();
m_criterions.append(criterion); m_criterions.append(criterion);
} }
bool DolphinSearchOptionsConfigurator::hasSearchParameters() const
{
if (!m_customSearchQuery.isEmpty()) {
// performance optimization: if a custom search query is defined,
// there is no need to call the (quite expensive) method nepomukUrl()
return true;
}
return nepomukUrl().path() != QLatin1String("/");
}
#include "dolphinsearchoptionsconfigurator.moc" #include "dolphinsearchoptionsconfigurator.moc"

View file

@ -20,7 +20,9 @@
#ifndef DOLPHINSEARCHOPTIONSCONFIGURATOR_H #ifndef DOLPHINSEARCHOPTIONSCONFIGURATOR_H
#define DOLPHINSEARCHOPTIONSCONFIGURATOR_H #define DOLPHINSEARCHOPTIONSCONFIGURATOR_H
#include <kurl.h>
#include <QList> #include <QList>
#include <QString>
#include <QWidget> #include <QWidget>
class KComboBox; class KComboBox;
@ -40,22 +42,30 @@ public:
virtual ~DolphinSearchOptionsConfigurator(); virtual ~DolphinSearchOptionsConfigurator();
/** /**
* Returns the configured options as compliant * Returns the sum of the configured options and the
* string that may be used as input for a nepomuk:/-URI. * custom search query as Nepomuk URL.
* @see DolphinSearchOptionsConfigurator::setCustomSearchQuery()
*/ */
QString options() const; KUrl nepomukUrl() const;
public slots:
/**
* Sets a custom search query that is added to the
* search query defined by the search options configurator.
* This is useful if a custom search user interface is
* offered outside the search options configurator.
*/
void setCustomSearchQuery(const QString& searchQuery);
signals: signals:
void searchOptionsChanged(const QString& options); void searchOptionsChanged();
protected: protected:
virtual void showEvent(QShowEvent* event); virtual void showEvent(QShowEvent* event);
private slots: private slots:
void slotAddSelectorButtonClicked(); void slotAddSelectorButtonClicked();
void slotCriterionChanged();
void emitSearchOptionsChanged();
void removeCriterion(); void removeCriterion();
/** /**
@ -76,13 +86,22 @@ private:
*/ */
void addCriterion(SearchCriterionSelector* selector); void addCriterion(SearchCriterionSelector* selector);
/**
* Returns true, DolphinSearchOptionsConfigurator::nepomukUrl()
* contains at least 1 search parameter.
*/
bool hasSearchParameters() const;
private: private:
bool m_initialized; bool m_initialized;
KComboBox* m_searchFromBox; KComboBox* m_locationBox;
KComboBox* m_searchWhatBox; KComboBox* m_whatBox;
QPushButton* m_addSelectorButton; QPushButton* m_addSelectorButton;
QPushButton* m_searchButton;
QPushButton* m_saveButton;
QVBoxLayout* m_vBoxLayout; QVBoxLayout* m_vBoxLayout;
QList<SearchCriterionSelector*> m_criterions; QList<SearchCriterionSelector*> m_criterions;
QString m_customSearchQuery;
}; };
#endif #endif

View file

@ -103,6 +103,11 @@ QString SearchCriterionSelector::toString() const
return criterion; return criterion;
} }
SearchCriterionSelector::Type SearchCriterionSelector::type() const
{
return static_cast<Type>(m_descriptionsBox->currentIndex());
}
void SearchCriterionSelector::slotDescriptionChanged(int index) void SearchCriterionSelector::slotDescriptionChanged(int index)
{ {
if (m_valueWidget != 0) { if (m_valueWidget != 0) {

View file

@ -56,6 +56,8 @@ public:
*/ */
QString toString() const; QString toString() const;
Type type() const;
signals: signals:
/** /**
* Is emitted if the criterion selector should be removed * Is emitted if the criterion selector should be removed