* 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/statusbarmessagelabel.cpp
zoomlevelinfo.cpp
)
)
kde4_add_kcfg_files(dolphin_SRCS
panels/folders/dolphin_folderspanelsettings.kcfgc
panels/information/dolphin_informationpanelsettings.kcfgc)
panels/information/dolphin_informationpanelsettings.kcfgc
search/dolphin_searchsettings.kcfgc
)
if(Nepomuk_FOUND)
set(dolphin_SRCS

View file

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

View file

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

View file

@ -87,6 +87,12 @@ signals:
*/
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
* requests the need for a UI that allows to adjust

View file

@ -19,6 +19,7 @@
#include "dolphinsearchoptionsconfigurator.h"
#include "dolphin_searchsettings.h"
#include "searchcriterionselector.h"
#include <kcombobox.h>
@ -35,32 +36,72 @@
#include <QShowEvent>
#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) :
QWidget(parent),
m_initialized(false),
m_searchFromBox(0),
m_searchWhatBox(0),
m_locationBox(0),
m_whatBox(0),
m_addSelectorButton(0),
m_searchButton(0),
m_saveButton(0),
m_vBoxLayout(0),
m_criterions()
m_criterions(),
m_customSearchQuery()
{
m_vBoxLayout = new QVBoxLayout(this);
// add "search" configuration
QLabel* searchLabel = new QLabel(i18nc("@label", "Search:"));
m_searchFromBox = new KComboBox(this);
m_searchFromBox->addItem(i18nc("@label", "Everywhere"));
m_searchFromBox->addItem(i18nc("@label", "From Here"));
m_locationBox = new KComboBox(this);
for (unsigned int i = 0; i < sizeof(g_locationItems) / sizeof(SettingsItem); ++i) {
m_locationBox->addItem(g_locationItems[i].text);
}
// add "what" configuration
QLabel* whatLabel = new QLabel(i18nc("@label", "What:"));
m_searchWhatBox = new KComboBox(this);
m_searchWhatBox->addItem(i18nc("@label", "All"));
m_searchWhatBox->addItem(i18nc("@label", "Images"));
m_searchWhatBox->addItem(i18nc("@label", "Text"));
m_searchWhatBox->addItem(i18nc("@label", "Filenames"));
m_whatBox = new KComboBox(this);
for (unsigned int i = 0; i < sizeof(g_whatItems) / sizeof(SettingsItem); ++i) {
m_whatBox->addItem(g_whatItems[i].text);
}
// add "Add selector" button
m_addSelectorButton = new QPushButton(this);
@ -70,18 +111,20 @@ DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* pare
connect(m_addSelectorButton, SIGNAL(clicked()), this, SLOT(slotAddSelectorButtonClicked()));
// add button "Search"
QPushButton* searchButton = new QPushButton(this);
searchButton->setIcon(KIcon("edit-find"));
searchButton->setText(i18nc("@action:button", "Search"));
searchButton->setToolTip(i18nc("@info", "Start searching"));
connect(searchButton, SIGNAL(clicked()), this, SLOT(emitSearchOptionsChanged()));
m_searchButton = new QPushButton(this);
m_searchButton->setIcon(KIcon("edit-find"));
m_searchButton->setText(i18nc("@action:button", "Search"));
m_searchButton->setToolTip(i18nc("@info", "Start searching"));
m_searchButton->setEnabled(false);
connect(m_searchButton, SIGNAL(clicked()), this, SIGNAL(searchOptionsChanged()));
// add button "Save"
QPushButton* saveButton = new QPushButton(this);
saveButton->setIcon(KIcon("document-save"));
saveButton->setText(i18nc("@action:button", "Save"));
saveButton->setToolTip(i18nc("@info", "Save search options"));
connect(saveButton, SIGNAL(clicked()), this, SLOT(saveQuery()));
m_saveButton = new QPushButton(this);
m_saveButton->setIcon(KIcon("document-save"));
m_saveButton->setText(i18nc("@action:button", "Save"));
m_saveButton->setToolTip(i18nc("@info", "Save search options"));
m_saveButton->setEnabled(false);
connect(m_saveButton, SIGNAL(clicked()), this, SLOT(saveQuery()));
// add button "Close"
QPushButton* closeButton = new QPushButton(this);
@ -90,31 +133,45 @@ DolphinSearchOptionsConfigurator::DolphinSearchOptionsConfigurator(QWidget* pare
closeButton->setToolTip(i18nc("@info", "Close search options"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(hide()));
QHBoxLayout* firstLineLayout = new QHBoxLayout();
firstLineLayout->addWidget(searchLabel);
firstLineLayout->addWidget(m_searchFromBox);
firstLineLayout->addWidget(whatLabel);
firstLineLayout->addWidget(m_searchWhatBox);
firstLineLayout->addWidget(new QWidget(this), 1); // filler
QHBoxLayout* lastLineLayout = new QHBoxLayout();
lastLineLayout->addWidget(m_addSelectorButton);
lastLineLayout->addWidget(new QWidget(this), 1); // filler
lastLineLayout->addWidget(searchButton);
lastLineLayout->addWidget(saveButton);
lastLineLayout->addWidget(closeButton);
QHBoxLayout* topLineLayout = new QHBoxLayout();
topLineLayout->addWidget(m_addSelectorButton);
topLineLayout->addWidget(searchLabel);
topLineLayout->addWidget(m_locationBox);
topLineLayout->addWidget(whatLabel);
topLineLayout->addWidget(m_whatBox);
topLineLayout->addWidget(new QWidget(this), 1); // filler
topLineLayout->addWidget(m_searchButton);
topLineLayout->addWidget(m_saveButton);
topLineLayout->addWidget(closeButton);
m_vBoxLayout->addWidget(new KSeparator(this));
m_vBoxLayout->addLayout(firstLineLayout);
m_vBoxLayout->addLayout(lastLineLayout);
m_vBoxLayout->addLayout(topLineLayout);
m_vBoxLayout->addWidget(new KSeparator(this));
}
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;
foreach (const SearchCriterionSelector* criterion, m_criterions) {
@ -126,25 +183,58 @@ QString DolphinSearchOptionsConfigurator::options() const
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)
{
if (!event->spontaneous() && !m_initialized) {
// add default search criterions
SearchCriterionSelector* dateCriterion = new SearchCriterionSelector(SearchCriterionSelector::Date, this);
SearchCriterionSelector* sizeCriterion = new SearchCriterionSelector(SearchCriterionSelector::Size, this);
SearchCriterionSelector* tagCriterion = new SearchCriterionSelector(SearchCriterionSelector::Tag, this);
// restore the UI layout of the last session
const QString location = SearchSettings::location();
for (unsigned int i = 0; i < sizeof(g_locationItems) / sizeof(SettingsItem); ++i) {
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
// is not mandatory from an implementation point of view, but preferable from a usability point of view.
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Date) == 0);
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Size) == 1);
Q_ASSERT(static_cast<int>(SearchCriterionSelector::Tag) == 2);
addCriterion(dateCriterion);
addCriterion(sizeCriterion);
addCriterion(tagCriterion);
const QString what = SearchSettings::what();
for (unsigned int i = 0; i < sizeof(g_whatItems) / sizeof(SettingsItem); ++i) {
if (g_whatItems[i].settingsName == what) {
m_whatBox->setCurrentIndex(i);
break;
}
}
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;
}
@ -153,13 +243,15 @@ void DolphinSearchOptionsConfigurator::showEvent(QShowEvent* event)
void DolphinSearchOptionsConfigurator::slotAddSelectorButtonClicked()
{
SearchCriterionSelector* selector = new SearchCriterionSelector(SearchCriterionSelector::Tag, this);
SearchCriterionSelector* selector = new SearchCriterionSelector(SearchCriterionSelector::Date, this);
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()
@ -211,18 +303,24 @@ void DolphinSearchOptionsConfigurator::saveQuery()
void DolphinSearchOptionsConfigurator::addCriterion(SearchCriterionSelector* criterion)
{
connect(criterion, SIGNAL(removeCriterion()), this, SLOT(removeCriterion()));
// TODO: It is unclear yet whether changing a criterion should also result in triggering
// 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()));
connect(criterion, SIGNAL(criterionChanged()), this, SLOT(slotCriterionChanged()));
// insert the new selector before the lastLineLayout and the KSeparator at the bottom
const int index = m_vBoxLayout->count() - 2;
// insert the new selector before the KSeparator at the bottom
const int index = m_vBoxLayout->count() - 1;
m_vBoxLayout->insertWidget(index, criterion);
updateSelectorButton();
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"

View file

@ -20,7 +20,9 @@
#ifndef DOLPHINSEARCHOPTIONSCONFIGURATOR_H
#define DOLPHINSEARCHOPTIONSCONFIGURATOR_H
#include <kurl.h>
#include <QList>
#include <QString>
#include <QWidget>
class KComboBox;
@ -40,22 +42,30 @@ public:
virtual ~DolphinSearchOptionsConfigurator();
/**
* Returns the configured options as compliant
* string that may be used as input for a nepomuk:/-URI.
* Returns the sum of the configured options and the
* 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:
void searchOptionsChanged(const QString& options);
void searchOptionsChanged();
protected:
virtual void showEvent(QShowEvent* event);
private slots:
void slotAddSelectorButtonClicked();
void emitSearchOptionsChanged();
void slotCriterionChanged();
void removeCriterion();
/**
@ -76,13 +86,22 @@ private:
*/
void addCriterion(SearchCriterionSelector* selector);
/**
* Returns true, DolphinSearchOptionsConfigurator::nepomukUrl()
* contains at least 1 search parameter.
*/
bool hasSearchParameters() const;
private:
bool m_initialized;
KComboBox* m_searchFromBox;
KComboBox* m_searchWhatBox;
KComboBox* m_locationBox;
KComboBox* m_whatBox;
QPushButton* m_addSelectorButton;
QPushButton* m_searchButton;
QPushButton* m_saveButton;
QVBoxLayout* m_vBoxLayout;
QList<SearchCriterionSelector*> m_criterions;
QString m_customSearchQuery;
};
#endif

View file

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

View file

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