From 67f58d5082cbab3a1a4a83926e77ade299ec07ea Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 25 Apr 2012 02:16:35 +0200 Subject: [PATCH] Fix search-UI issues in combination with the new places entries The places-entries for searching revealed some serious issues in combination with the search-panel. Move the filtering away from QDockWidget and bring it back below the search-bar. --- src/CMakeLists.txt | 5 +- src/dolphinmainwindow.cpp | 113 +---------- src/dolphinmainwindow.h | 15 -- src/dolphinviewcontainer.cpp | 12 -- src/dolphinviewcontainer.h | 10 - src/panels/places/placespanel.cpp | 6 +- src/panels/search/searchpanel.cpp | 271 ------------------------- src/panels/search/searchpanel.h | 107 ---------- src/search/dolphin_searchsettings.kcfg | 4 + src/search/dolphinfacetswidget.cpp | 108 ++++++++++ src/search/dolphinfacetswidget.h | 73 +++++++ src/search/dolphinsearchbox.cpp | 40 ++++ src/search/dolphinsearchbox.h | 8 +- src/tests/CMakeLists.txt | 1 + 14 files changed, 237 insertions(+), 536 deletions(-) delete mode 100644 src/panels/search/searchpanel.cpp delete mode 100644 src/panels/search/searchpanel.h create mode 100644 src/search/dolphinfacetswidget.cpp create mode 100644 src/search/dolphinfacetswidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d0519da9c..94ae5aa77c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -147,6 +147,7 @@ set(dolphin_SRCS panels/panel.cpp panels/folders/treeviewcontextmenu.cpp panels/folders/folderspanel.cpp + search/dolphinfacetswidget.cpp search/dolphinsearchbox.cpp search/dolphinsearchinformation.cpp settings/general/behaviorsettingspage.cpp @@ -183,10 +184,6 @@ kde4_add_kcfg_files(dolphin_SRCS settings/dolphin_versioncontrolsettings.kcfgc ) -if(Nepomuk_FOUND) - set(dolphin_SRCS ${dolphin_SRCS} panels/search/searchpanel.cpp) -endif(Nepomuk_FOUND) - if(NOT WIN32) set(dolphin_SRCS ${dolphin_SRCS} panels/terminal/terminalpanel.cpp) endif(NOT WIN32) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 209b106785..3eb9b76084 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -21,22 +21,14 @@ #include "dolphinmainwindow.h" -#include - #include "dolphinapplication.h" #include "dolphindockwidget.h" #include "dolphincontextmenu.h" #include "dolphinnewfilemenu.h" #include "dolphinviewcontainer.h" -#ifdef HAVE_NEPOMUK - #include "panels/search/searchpanel.h" - #include -#endif #include "panels/folders/folderspanel.h" #include "panels/places/placespanel.h" #include "panels/information/informationpanel.h" -#include "search/dolphinsearchbox.h" -#include "search/dolphinsearchinformation.h" #include "settings/dolphinsettingsdialog.h" #include "statusbar/dolphinstatusbar.h" #include "views/dolphinviewactionhandler.h" @@ -49,7 +41,6 @@ #endif #include "dolphin_generalsettings.h" -#include "dolphin_searchsettings.h" #include #include @@ -130,8 +121,7 @@ DolphinMainWindow::DolphinMainWindow() : m_settingsDialog(), m_controlButton(0), m_updateToolBarTimer(0), - m_lastHandleUrlStatJob(0), - m_searchDockIsTemporaryVisible(false) + m_lastHandleUrlStatJob(0) { DolphinPlacesModel::setModel(new KFilePlacesModel(this)); connect(DolphinPlacesModel::instance(), SIGNAL(errorMessage(QString)), @@ -637,14 +627,6 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event) GeneralSettings::setVersion(CurrentDolphinVersion); GeneralSettings::self()->writeConfig(); - if (m_searchDockIsTemporaryVisible) { - QDockWidget* searchDock = findChild("searchDock"); - if (searchDock) { - searchDock->hide(); - } - m_searchDockIsTemporaryVisible = false; - } - KXmlGuiWindow::closeEvent(event); } @@ -805,23 +787,6 @@ void DolphinMainWindow::find() m_activeViewContainer->setSearchModeEnabled(true); } -void DolphinMainWindow::slotSearchLocationChanged() -{ -#ifdef HAVE_NEPOMUK - QDockWidget* searchDock = findChild("searchDock"); - if (!searchDock) { - return; - } - - SearchPanel* searchPanel = qobject_cast(searchDock->widget()); - if (searchPanel) { - searchPanel->setSearchLocation(SearchSettings::location() == QLatin1String("FromHere") - ? SearchPanel::FromCurrentDir - : SearchPanel::Everywhere); - } -#endif -} - void DolphinMainWindow::updatePasteAction() { QAction* pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste)); @@ -1323,52 +1288,6 @@ void DolphinMainWindow::slotWriteStateChanged(bool isFolderWritable) newFileMenu()->setEnabled(isFolderWritable); } -void DolphinMainWindow::slotSearchModeChanged(bool enabled) -{ -#ifdef HAVE_NEPOMUK - const DolphinSearchInformation& searchInfo = DolphinSearchInformation::instance(); - if (!searchInfo.isIndexingEnabled()) { - return; - } - - QDockWidget* searchDock = findChild("searchDock"); - if (!searchDock) { - return; - } - - if (enabled) { - if (!searchDock->isVisible()) { - m_searchDockIsTemporaryVisible = true; - } - searchDock->show(); - } else { - if (searchDock->isVisible() && m_searchDockIsTemporaryVisible) { - searchDock->hide(); - } - m_searchDockIsTemporaryVisible = false; - } - - SearchPanel* searchPanel = qobject_cast(searchDock->widget()); - if (!searchPanel) { - return; - } - - if (enabled) { - SearchPanel::SearchLocation searchLocation = SearchPanel::Everywhere; - const KUrl url = m_activeViewContainer->url(); - const bool isSearchUrl = (url.protocol() == QLatin1String("nepomuksearch")); - if ((SearchSettings::location() == QLatin1String("FromHere") && !isSearchUrl)) { - searchLocation = SearchPanel::FromCurrentDir; - } - searchPanel->setSearchLocation(searchLocation); - } else { - searchPanel->setSearchLocation(SearchPanel::Everywhere); - } -#else - Q_UNUSED(enabled); -#endif -} - void DolphinMainWindow::openContextMenu(const QPoint& pos, const KFileItem& item, const KUrl& url, @@ -1804,32 +1723,11 @@ void DolphinMainWindow::setupDockWidgets() terminalPanel, SLOT(setUrl(KUrl))); #endif - // Setup "Search" -#ifdef HAVE_NEPOMUK - DolphinDockWidget* searchDock = new DolphinDockWidget(i18nc("@title:window", "Search")); - searchDock->setLocked(lock); - searchDock->setObjectName("searchDock"); - searchDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - Panel* searchPanel = new SearchPanel(searchDock); - searchPanel->setCustomContextMenuActions(QList() << lockLayoutAction); - connect(searchPanel, SIGNAL(urlActivated(KUrl)), this, SLOT(handleUrl(KUrl))); - searchDock->setWidget(searchPanel); - - QAction* searchAction = searchDock->toggleViewAction(); - createPanelAction(KIcon("system-search"), Qt::Key_F12, searchAction, "show_search_panel"); - addDockWidget(Qt::RightDockWidgetArea, searchDock); - connect(this, SIGNAL(urlChanged(KUrl)), - searchPanel, SLOT(setUrl(KUrl))); -#endif - if (GeneralSettings::version() < 200) { infoDock->hide(); foldersDock->hide(); #ifndef Q_OS_WIN terminalDock->hide(); -#endif -#ifdef HAVE_NEPOMUK - searchDock->hide(); #endif } @@ -1873,9 +1771,6 @@ void DolphinMainWindow::setupDockWidgets() panelsMenu->addAction(ac->action("show_folders_panel")); #ifndef Q_OS_WIN panelsMenu->addAction(ac->action("show_terminal_panel")); -#endif -#ifdef HAVE_NEPOMUK - panelsMenu->addAction(ac->action("show_search_panel")); #endif panelsMenu->addSeparator(); panelsMenu->addAction(lockLayoutAction); @@ -2068,12 +1963,6 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) this, SLOT(updateFilterBarAction(bool))); connect(container, SIGNAL(writeStateChanged(bool)), this, SLOT(slotWriteStateChanged(bool))); - connect(container, SIGNAL(searchModeChanged(bool)), - this, SLOT(slotSearchModeChanged(bool))); - - const DolphinSearchBox* searchBox = container->searchBox(); - connect(searchBox, SIGNAL(searchLocationChanged(SearchLocation)), - this, SLOT(slotSearchLocationChanged())); DolphinView* view = container->view(); connect(view, SIGNAL(selectionChanged(KFileItemList)), diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index dec064d113..4bc3c8d4dd 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -207,13 +207,6 @@ private slots: /** Replaces the URL navigator by a search box to find files. */ void find(); - /** - * Is invoked when the "Find" is active and the search location - * (From Here/Everywhere) has been changed. Updates the - * enabled state of the Search Panel. - */ - void slotSearchLocationChanged(); - /** * Updates the text of the paste action dependent on * the number of items which are in the clipboard. @@ -440,8 +433,6 @@ private slots: */ void slotWriteStateChanged(bool isFolderWritable); - void slotSearchModeChanged(bool enabled); - /** * Opens the context menu on the current mouse position. * @pos Position in screen coordinates. @@ -587,12 +578,6 @@ private: QTimer* m_updateToolBarTimer; KIO::Job* m_lastHandleUrlStatJob; - - /** - * Set to true, if the filter dock visibility is only temporary set - * to true by enabling the search mode. - */ - bool m_searchDockIsTemporaryVisible; }; inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index ce602be995..22be3a8332 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -210,16 +210,6 @@ DolphinView* DolphinViewContainer::view() return m_view; } -const DolphinSearchBox* DolphinViewContainer::searchBox() const -{ - return m_searchBox; -} - -DolphinSearchBox* DolphinViewContainer::searchBox() -{ - return m_searchBox; -} - void DolphinViewContainer::showMessage(const QString& msg, MessageType type) { if (msg.isEmpty()) { @@ -308,8 +298,6 @@ void DolphinViewContainer::setSearchModeEnabled(bool enabled) } } } - - emit searchModeChanged(enabled); } bool DolphinViewContainer::isSearchModeEnabled() const diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index db9b5be336..10dd67246c 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -88,9 +88,6 @@ public: const DolphinView* view() const; DolphinView* view(); - const DolphinSearchBox* searchBox() const; - DolphinSearchBox* searchBox(); - /** * Shows the message \msg with the given type non-modal above * the view-content. @@ -142,13 +139,6 @@ signals: */ void writeStateChanged(bool isFolderWritable); - /** - * Is emitted if the search mode has been enabled or disabled. - * (see DolphinViewContainer::setSearchModeEnabled() and - * DolphinViewContainer::isSearchModeEnabled()) - */ - void searchModeChanged(bool enabled); - private slots: /** * Updates the number of items (= number of files + number of diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index d13eb08125..09287169ce 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -204,9 +204,9 @@ void PlacesPanel::createDefaultBookmarks() "folder-image", i18nc("@item Commonly Accessed", "Images"), searchForGroup)); - m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/music"), + m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/audio"), "folder-sound", - i18nc("@item Commonly Accessed", "Music"), + i18nc("@item Commonly Accessed", "Audio"), searchForGroup)); m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/videos"), "folder-video", @@ -357,7 +357,7 @@ KUrl PlacesPanel::createSearchUrl(const KUrl& url) searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Document())); } else if (path.endsWith("images")) { searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Image())); - } else if (path.endsWith("music")) { + } else if (path.endsWith("audio")) { searchUrl = searchUrlForTerm(Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(), Nepomuk::Query::LiteralTerm("audio"))); } else if (path.endsWith("videos")) { diff --git a/src/panels/search/searchpanel.cpp b/src/panels/search/searchpanel.cpp deleted file mode 100644 index fd4195f54c..0000000000 --- a/src/panels/search/searchpanel.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Sebastian Trueg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "searchpanel.h" - -#include "dolphin_searchsettings.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -SearchPanel::SearchPanel(QWidget* parent) : - Panel(parent), - m_initialized(false), - m_searchLocation(Everywhere), - m_lastSetUrlStatJob(0), - m_startedFromDir(), - m_facetWidget(0), - m_unfacetedRestQuery() -{ - setEnabled(false); -} - -SearchPanel::~SearchPanel() -{ -} - -void SearchPanel::setSearchLocation(SearchLocation location) -{ - m_searchLocation = location; - if (isVisible()) { - setEnabled(isFilteringPossible()); - } -} - -SearchPanel::SearchLocation SearchPanel::searchLocation() const -{ - return m_searchLocation; -} - -bool SearchPanel::urlChanged() -{ - const bool isNepomukUrl = url().protocol().startsWith(QLatin1String("nepomuk")); - if (!isNepomukUrl) { - // Remember the current directory before a searching is started. - // This is required to restore the directory in case that all facets - // have been reset by the user (see slotQueryTermChanged()). - m_startedFromDir = url(); - } - - if (isVisible() && DolphinSearchInformation::instance().isIndexingEnabled()) { - const Nepomuk::Query::FileQuery query(m_unfacetedRestQuery && m_facetWidget->queryTerm()); - if (query.toSearchUrl() == url()) { - // The new URL has been triggered by the SearchPanel itself in - // slotQueryTermChanged() and no further handling is required. - return true; - } - - delete m_lastSetUrlStatJob; - m_lastSetUrlStatJob = 0; - - if (isNepomukUrl) { - // Reset the current query and disable the facet-widget until - // the new query has been determined by KIO::stat(): - m_lastSetUrlStatJob = KIO::stat(url(), KIO::HideProgressInfo); - if (m_lastSetUrlStatJob->ui()) { - m_lastSetUrlStatJob->ui()->setWindow(this); - } - connect(m_lastSetUrlStatJob, SIGNAL(result(KJob*)), - this, SLOT(slotSetUrlStatFinished(KJob*))); - } else { - // Reset the search panel because a "normal" directory is shown. - setQuery(Nepomuk::Query::Query()); - } - - setEnabled(isFilteringPossible()); - } - - return true; -} - -void SearchPanel::showEvent(QShowEvent* event) -{ - if (event->spontaneous()) { - Panel::showEvent(event); - return; - } - - if (!m_initialized) { - QVBoxLayout* layout = new QVBoxLayout(this); - layout->setMargin(0); - - Q_ASSERT(!m_facetWidget); - m_facetWidget = new Nepomuk::Utils::FacetWidget(this); - layout->addWidget(m_facetWidget, 1); - - // File Type - m_facetWidget->addFacet(Nepomuk::Utils::Facet::createFileTypeFacet()); - - // Image Size - Nepomuk::Utils::ProxyFacet* imageSizeProxy = new Nepomuk::Utils::ProxyFacet(); - imageSizeProxy->setFacetCondition(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Image())); - Nepomuk::Utils::SimpleFacet* imageSizeFacet = new Nepomuk::Utils::SimpleFacet(imageSizeProxy); - imageSizeFacet->setSelectionMode(Nepomuk::Utils::Facet::MatchAny); - imageSizeFacet->addTerm( i18nc("option:check Refers to a filter on image size", "Small"), - Nepomuk::Vocabulary::NFO::width() <= Nepomuk::Query::LiteralTerm(300)); - imageSizeFacet->addTerm( i18nc("option:check Refers to a filter on image size", "Medium"), - (Nepomuk::Vocabulary::NFO::width() > Nepomuk::Query::LiteralTerm(300)) && - (Nepomuk::Vocabulary::NFO::width() <= Nepomuk::Query::LiteralTerm(800))); - imageSizeFacet->addTerm( i18nc("option:check Refers to a filter on image size", "Large"), - Nepomuk::Vocabulary::NFO::width() > Nepomuk::Query::LiteralTerm(800)); - imageSizeProxy->setSourceFacet(imageSizeFacet); - m_facetWidget->addFacet(imageSizeProxy); - - // Artists - Nepomuk::Utils::ProxyFacet* artistProxy = new Nepomuk::Utils::ProxyFacet(); - artistProxy->setFacetCondition(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Audio()) || - Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(), - Nepomuk::Query::LiteralTerm(QLatin1String("audio")))); - Nepomuk::Utils::DynamicResourceFacet* artistFacet = new Nepomuk::Utils::DynamicResourceFacet(artistProxy); - artistFacet->setSelectionMode(Nepomuk::Utils::Facet::MatchAny); - artistFacet->setRelation(Nepomuk::Vocabulary::NMM::performer()); - artistProxy->setSourceFacet(artistFacet); - m_facetWidget->addFacet(artistProxy); - - // Misc - m_facetWidget->addFacet(Nepomuk::Utils::Facet::createDateFacet()); - m_facetWidget->addFacet(Nepomuk::Utils::Facet::createRatingFacet()); - m_facetWidget->addFacet(Nepomuk::Utils::Facet::createTagFacet()); - - connect(m_facetWidget, SIGNAL(queryTermChanged(Nepomuk::Query::Term)), - this, SLOT(slotQueryTermChanged(Nepomuk::Query::Term))); - - m_initialized = true; - } - - setEnabled(isFilteringPossible()); - - Panel::showEvent(event); -} - -void SearchPanel::contextMenuEvent(QContextMenuEvent* event) -{ - Panel::contextMenuEvent(event); - - QWeakPointer popup = new KMenu(this); - foreach (QAction* action, customContextMenuActions()) { - popup.data()->addAction(action); - } - popup.data()->exec(QCursor::pos()); - delete popup.data(); -} - -void SearchPanel::slotSetUrlStatFinished(KJob* job) -{ - m_lastSetUrlStatJob = 0; - - setEnabled(isFilteringPossible()); - - const KIO::UDSEntry uds = static_cast(job)->statResult(); - const QString nepomukQueryStr = uds.stringValue(KIO::UDSEntry::UDS_NEPOMUK_QUERY); - const Nepomuk::Query::Term facetQueryTerm = m_facetWidget->queryTerm(); - Nepomuk::Query::FileQuery nepomukQuery; - if (!nepomukQueryStr.isEmpty()) { - // Always merge the query that has been retrieved by SearchPanel::setUrl() with - // the current facet-query, so that the user settings don't get lost. - nepomukQuery = Nepomuk::Query::Query::fromString(nepomukQueryStr) && m_facetWidget->queryTerm(); - } - - setQuery(nepomukQuery); - - if (facetQueryTerm.isValid()) { - Nepomuk::Query::FileQuery query(m_unfacetedRestQuery && facetQueryTerm); - emit urlActivated(query.toSearchUrl()); - } -} - -void SearchPanel::slotQueryTermChanged(const Nepomuk::Query::Term& term) -{ - if (term.isValid()) { - // Default case: A facet has been changed by the user to restrict the query. - if ((m_searchLocation == FromCurrentDir) && !m_unfacetedRestQuery.isValid()) { - // Adjust the query to respect the FromCurrentDir setting - Nepomuk::Query::ComparisonTerm compTerm( - Nepomuk::Vocabulary::NFO::fileName(), - Nepomuk::Query::Term()); - - Nepomuk::Query::FileQuery subDirsQuery; - subDirsQuery.setFileMode(Nepomuk::Query::FileQuery::QueryFiles); - subDirsQuery.addIncludeFolder(m_startedFromDir, true); - subDirsQuery.setTerm(compTerm); - - setQuery(subDirsQuery); - } - - Nepomuk::Query::FileQuery query(m_unfacetedRestQuery && term); - emit urlActivated(query.toSearchUrl()); - return; - } - - // All facets have been reset by the user to be unrestricted. - // Verify whether the unfaceted rest query contains any additional restriction - // (e.g. a filename in the search field). If no further restriction is given, exit - // the search mode by returning to the directory where the searching has been - // started from. - const Nepomuk::Query::Term rootTerm = m_unfacetedRestQuery.term(); - if (rootTerm.type() == Nepomuk::Query::Term::Comparison) { - const Nepomuk::Query::ComparisonTerm& compTerm = static_cast(rootTerm); - if (compTerm.subTerm().isValid()) { - Nepomuk::Query::FileQuery query(m_unfacetedRestQuery); - emit urlActivated(query.toSearchUrl()); - return; - } - } - - emit urlActivated(m_startedFromDir); -} - -void SearchPanel::setQuery(const Nepomuk::Query::Query& query) -{ - const bool block = m_facetWidget->blockSignals(true); - m_unfacetedRestQuery = m_facetWidget->extractFacetsFromQuery(query); - m_facetWidget->setClientQuery(query); - m_facetWidget->blockSignals(block); -} - -bool SearchPanel::isFilteringPossible() const -{ - const DolphinSearchInformation& searchInfo = DolphinSearchInformation::instance(); - return searchInfo.isIndexingEnabled() - && ((m_searchLocation == Everywhere) || searchInfo.isPathIndexed(m_startedFromDir)); -} diff --git a/src/panels/search/searchpanel.h b/src/panels/search/searchpanel.h deleted file mode 100644 index 4ea7e121e9..0000000000 --- a/src/panels/search/searchpanel.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Sebastian Trueg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef SEARCHPANEL_H -#define SEARCHPANEL_H - -#include -#include - -namespace KIO -{ - class Job; -}; - -namespace Nepomuk -{ - namespace Utils - { - class FacetWidget; - } -} - -/** - * @brief Allows to search for files by enabling generic search patterns (= facets). - * - * For example it is possible to search for images, documents or specific tags. - * The search panel can be adjusted to search only from the current folder or everywhere. - */ -class SearchPanel : public Panel -{ - Q_OBJECT - -public: - enum SearchLocation - { - Everywhere, - FromCurrentDir - }; - - SearchPanel(QWidget* parent = 0); - virtual ~SearchPanel(); - - /** - * Specifies whether a searching is done in all folders (= Everywhere) - * or from the current directory (= FromCurrentDir). The current directory - * is automatically determined when setUrl() has been called. - */ - void setSearchLocation(SearchLocation location); - SearchLocation searchLocation() const; - -signals: - void urlActivated(const KUrl& url); - -protected: - /** @see Panel::urlChanged() */ - virtual bool urlChanged(); - - /** @see QWidget::showEvent() */ - virtual void showEvent(QShowEvent* event); - - /** @see QWidget::contextMenuEvent() */ - virtual void contextMenuEvent(QContextMenuEvent* event); - -private slots: - void slotSetUrlStatFinished(KJob*); - void slotQueryTermChanged(const Nepomuk::Query::Term& term); - -private: - void setQuery(const Nepomuk::Query::Query& query); - - /** - * @return True if the facets can be applied to the given URL - * and hence a filtering of the content is possible. - * False is returned if the search-mode is set to - * SearchLocation::FromCurrentDir and this directory is - * not indexed at all. Also if indexing is disabled - * false will be returned. - */ - bool isFilteringPossible() const; - -private: - bool m_initialized; - SearchLocation m_searchLocation; - KIO::Job* m_lastSetUrlStatJob; - - KUrl m_startedFromDir; - Nepomuk::Utils::FacetWidget* m_facetWidget; - Nepomuk::Query::Query m_unfacetedRestQuery; -}; - -#endif // SEARCHPANEL_H diff --git a/src/search/dolphin_searchsettings.kcfg b/src/search/dolphin_searchsettings.kcfg index 1acebf8749..81190d29e1 100644 --- a/src/search/dolphin_searchsettings.kcfg +++ b/src/search/dolphin_searchsettings.kcfg @@ -14,5 +14,9 @@ FileName + + + false + diff --git a/src/search/dolphinfacetswidget.cpp b/src/search/dolphinfacetswidget.cpp new file mode 100644 index 0000000000..1a912af481 --- /dev/null +++ b/src/search/dolphinfacetswidget.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** +* Copyright (C) 2012 by Peter Penz * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * +* **************************************************************************/ + +#include "dolphinfacetswidget.h" + +#include +#include +#include +#include +#include + +DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : + QWidget(parent), + m_documents(0), + m_images(0), + m_audio(0), + m_videos(0), + m_anytime(0), + m_today(0), + m_yesterday(0), + m_thisWeek(0), + m_thisMonth(0), + m_thisYear(0), + m_anyRating(0), + m_oneOrMore(0), + m_twoOrMore(0), + m_threeOrMore(0), + m_fourOrMore(0), + m_maxRating(0) +{ + m_documents = new QCheckBox(i18nc("@option:check", "Documents")); + m_images = new QCheckBox(i18nc("@option:check", "Images")); + m_audio = new QCheckBox(i18nc("@option:check", "Audio")); + m_videos = new QCheckBox(i18nc("@option:check", "Videos")); + + QVBoxLayout* typeLayout = new QVBoxLayout(); + typeLayout->setSpacing(0); + typeLayout->addWidget(m_documents); + typeLayout->addWidget(m_images); + typeLayout->addWidget(m_audio); + typeLayout->addWidget(m_videos); + typeLayout->addStretch(); + + m_anytime = new QRadioButton(i18nc("@option:option", "Anytime")); + m_today = new QRadioButton(i18nc("@option:option", "Today")); + m_yesterday = new QRadioButton(i18nc("@option:option", "Yesterday")); + m_thisWeek = new QRadioButton(i18nc("@option:option", "This Week")); + m_thisMonth = new QRadioButton(i18nc("@option:option", "This Month")); + m_thisYear = new QRadioButton(i18nc("@option:option", "This Year")); + + QVBoxLayout* timespanLayout = new QVBoxLayout(); + timespanLayout->setSpacing(0); + timespanLayout->addWidget(m_anytime); + timespanLayout->addWidget(m_today); + timespanLayout->addWidget(m_yesterday); + timespanLayout->addWidget(m_thisWeek); + timespanLayout->addWidget(m_thisMonth); + timespanLayout->addWidget(m_thisYear); + timespanLayout->addStretch(); + + m_anyRating = new QRadioButton(i18nc("@option:option", "Any Rating")); + m_oneOrMore = new QRadioButton(i18nc("@option:option", "1 or more")); + m_twoOrMore = new QRadioButton(i18nc("@option:option", "2 or more")); + m_threeOrMore = new QRadioButton(i18nc("@option:option", "3 or more")); + m_fourOrMore = new QRadioButton(i18nc("@option:option", "4 or more")); + m_maxRating = new QRadioButton(i18nc("@option:option", "Maximum Rating")); + + QVBoxLayout* ratingLayout = new QVBoxLayout(); + ratingLayout->setSpacing(0); + ratingLayout->addWidget(m_anyRating); + ratingLayout->addWidget(m_oneOrMore); + ratingLayout->addWidget(m_twoOrMore); + ratingLayout->addWidget(m_threeOrMore); + ratingLayout->addWidget(m_fourOrMore); + ratingLayout->addWidget(m_maxRating); + + QHBoxLayout* topLayout = new QHBoxLayout(this); + topLayout->addLayout(typeLayout); + topLayout->addLayout(timespanLayout); + topLayout->addLayout(ratingLayout); + topLayout->addStretch(); + + // TODO: + m_anytime->setChecked(true); + m_anyRating->setChecked(true); +} + +DolphinFacetsWidget::~DolphinFacetsWidget() +{ +} + +#include "dolphinfacetswidget.moc" diff --git a/src/search/dolphinfacetswidget.h b/src/search/dolphinfacetswidget.h new file mode 100644 index 0000000000..916e056081 --- /dev/null +++ b/src/search/dolphinfacetswidget.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef DOLPHINFACETSWIDGET_H +#define DOLPHINFACETSWIDGET_H + +#include + +class QCheckBox; +class QRadioButton; + +/** + * @brief Allows to filter search-queries by facets. + * + * TODO: The current implementation is a temporary + * workaround for the 4.10 release and represents no + * real facets-implementation yet: There have been + * some Dolphin specific user-interface and interaction + * issues since 4.6 by embedding the Nepomuk facet-widget + * into a QDockWidget (this is unrelated to the + * Nepomuk facet-widget itself). Now in combination + * with the search-shortcuts in the Places Panel some + * existing issues turned into real showstoppers. + * + * So the longterm plan is to use the Nepomuk facets + * again as soon as possible. + */ +class DolphinFacetsWidget : public QWidget +{ + Q_OBJECT + +public: + explicit DolphinFacetsWidget(QWidget* parent = 0); + virtual ~DolphinFacetsWidget(); + +private: + QCheckBox* m_documents; + QCheckBox* m_images; + QCheckBox* m_audio; + QCheckBox* m_videos; + + QRadioButton* m_anytime; + QRadioButton* m_today; + QRadioButton* m_yesterday; + QRadioButton* m_thisWeek; + QRadioButton* m_thisMonth; + QRadioButton* m_thisYear; + + QRadioButton* m_anyRating; + QRadioButton* m_oneOrMore; + QRadioButton* m_twoOrMore; + QRadioButton* m_threeOrMore; + QRadioButton* m_fourOrMore; + QRadioButton* m_maxRating; +}; + +#endif diff --git a/src/search/dolphinsearchbox.cpp b/src/search/dolphinsearchbox.cpp index 06644e1f36..a9c960c24f 100644 --- a/src/search/dolphinsearchbox.cpp +++ b/src/search/dolphinsearchbox.cpp @@ -20,6 +20,7 @@ #include "dolphinsearchbox.h" #include "dolphin_searchsettings.h" +#include "dolphinfacetswidget.h" #include "dolphinsearchinformation.h" #include @@ -65,6 +66,8 @@ DolphinSearchBox::DolphinSearchBox(QWidget* parent) : m_separator(0), m_fromHereButton(0), m_everywhereButton(0), + m_facetsToggleButton(0), + m_facetsWidget(0), m_searchPath(), m_readOnlyQuery(), m_startSearchTimer(0) @@ -109,6 +112,10 @@ void DolphinSearchBox::setSearchPath(const KUrl& url) m_separator->setVisible(showSearchFromButtons); m_fromHereButton->setVisible(showSearchFromButtons); m_everywhereButton->setVisible(showSearchFromButtons); + + const DolphinSearchInformation& searchInfo = DolphinSearchInformation::instance(); + const bool hasFacetsSupport = searchInfo.isIndexingEnabled() && searchInfo.isPathIndexed(m_searchPath); + m_facetsWidget->setEnabled(hasFacetsSupport); } KUrl DolphinSearchBox::searchPath() const @@ -228,6 +235,14 @@ void DolphinSearchBox::slotReturnPressed(const QString& text) emit returnPressed(text); } +void DolphinSearchBox::slotFacetsButtonToggled() +{ + const bool visible = !m_facetsWidget->isVisible(); + m_facetsWidget->setVisible(visible); + SearchSettings::setShowFacetsWidget(visible); + updateFacetsToggleButtonIcon(); +} + void DolphinSearchBox::initButton(QToolButton* button) { button->setAutoExclusive(true); @@ -249,6 +264,8 @@ void DolphinSearchBox::loadSettings() } else { m_fileNameButton->setChecked(true); } + + m_facetsWidget->setVisible(SearchSettings::showFacetsWidget()); } void DolphinSearchBox::saveSettings() @@ -319,6 +336,14 @@ void DolphinSearchBox::init() connect(m_fromHereButton, SIGNAL(clicked()), this, SLOT(slotSearchLocationChanged())); connect(m_everywhereButton, SIGNAL(clicked()), this, SLOT(slotSearchLocationChanged())); + // Create "Facets" widgets + m_facetsToggleButton = new QToolButton(this); + m_facetsToggleButton->setAutoRaise(true); + connect(m_facetsToggleButton, SIGNAL(clicked()), this, SLOT(slotFacetsButtonToggled())); + + m_facetsWidget = new DolphinFacetsWidget(this); + m_facetsWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + // Apply layout for the options QHBoxLayout* optionsLayout = new QHBoxLayout(); optionsLayout->setMargin(0); @@ -328,6 +353,7 @@ void DolphinSearchBox::init() optionsLayout->addWidget(m_fromHereButton); optionsLayout->addWidget(m_everywhereButton); optionsLayout->addStretch(1); + optionsLayout->addWidget(m_facetsToggleButton); // Put the options into a QScrollArea. This prevents increasing the view width // in case that not enough width for the options is available. @@ -347,6 +373,7 @@ void DolphinSearchBox::init() m_topLayout->setMargin(0); m_topLayout->addLayout(searchInputLayout); m_topLayout->addWidget(m_optionsScrollArea); + m_topLayout->addWidget(m_facetsWidget); loadSettings(); @@ -357,6 +384,7 @@ void DolphinSearchBox::init() m_startSearchTimer->setInterval(1000); connect(m_startSearchTimer, SIGNAL(timeout()), this, SLOT(emitSearchSignal())); + updateFacetsToggleButtonIcon(); applyReadOnlyState(); } @@ -413,6 +441,18 @@ void DolphinSearchBox::applyReadOnlyState() m_searchInput->setVisible(!m_readOnly); m_optionsScrollArea->setVisible(!m_readOnly); + + if (m_readOnly) { + m_facetsWidget->hide(); + } else { + m_facetsWidget->setVisible(SearchSettings::showFacetsWidget()); + } +} + +void DolphinSearchBox::updateFacetsToggleButtonIcon() +{ + const bool visible = SearchSettings::showFacetsWidget(); + m_facetsToggleButton->setIcon(KIcon(visible ? "list-remove" : "list-add")); } #include "dolphinsearchbox.moc" diff --git a/src/search/dolphinsearchbox.h b/src/search/dolphinsearchbox.h index 8af32b377f..2b4632bb1a 100644 --- a/src/search/dolphinsearchbox.h +++ b/src/search/dolphinsearchbox.h @@ -24,10 +24,9 @@ #include #include -class AbstractSearchFilterWidget; +class DolphinFacetsWidget; class KLineEdit; class KSeparator; -class QFormLayout; class QToolButton; class QScrollArea; class QLabel; @@ -141,6 +140,7 @@ private slots: void slotConfigurationChanged(); void slotSearchTextChanged(const QString& text); void slotReturnPressed(const QString& text); + void slotFacetsButtonToggled(); private: void initButton(QToolButton* button); @@ -155,6 +155,8 @@ private: void applyReadOnlyState(); + void updateFacetsToggleButtonIcon(); + private: bool m_startedSearching; bool m_readOnly; @@ -169,6 +171,8 @@ private: KSeparator* m_separator; QToolButton* m_fromHereButton; QToolButton* m_everywhereButton; + QToolButton* m_facetsToggleButton; + DolphinFacetsWidget* m_facetsWidget; KUrl m_searchPath; KUrl m_readOnlyQuery; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index de254f6da9..830138e74b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -58,6 +58,7 @@ target_link_libraries(kitemlistkeyboardsearchmanagertest ${KDE4_KIO_LIBS} ${QT_Q if (Nepomuk_FOUND) set(dolphinsearchboxtest_SRCS dolphinsearchboxtest.cpp + ../search/dolphinfacetswidget.cpp ../search/dolphinsearchbox.cpp ../search/dolphinsearchinformation.cpp )