/*************************************************************************** * 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 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; 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); 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)); }