kdelibs/nepomuk/utils/searchwidget.cpp
2014-11-13 01:04:59 +02:00

316 lines
10 KiB
C++

/*
Copyright (c) 2010 Oszkar Ambrus <aoszkar@gmail.com>
Copyright (C) 2010 Sebastian Trueg <trueg@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "searchwidget.h"
#include "searchwidget_p.h"
#include "searchlineedit.h"
#include "facetwidget.h"
#include "simpleresourcemodel.h"
#include "proxyfacet.h"
#include "simplefacet.h"
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QListView>
#include <QtGui/QSplitter>
#include <QtCore/QList>
#include "kdebug.h"
#include "kpushbutton.h"
#include "kdialog.h"
#include "query.h"
#include "queryparser.h"
#include "result.h"
#include "andterm.h"
#include "orterm.h"
#include "literalterm.h"
#include "comparisonterm.h"
#include "resourceterm.h"
#include "resourcetypeterm.h"
#include "queryserviceclient.h"
#include "resource.h"
#include "filequery.h"
#include "negationterm.h"
#include "nfo.h"
#include "variant.h"
#include <Soprano/LiteralValue>
#include <Soprano/Vocabulary/NAO>
void Nepomuk::Utils::SearchWidget::SearchWidgetPrivate::setupFacetWidget()
{
m_facetWidget->clear();
m_facetWidget->addFacet(Facet::createTypeFacet(m_facetWidget));
m_facetWidget->addFacet(Facet::createDateFacet(m_facetWidget));
m_facetWidget->addFacet(Facet::createPriorityFacet(m_facetWidget));
m_facetWidget->addFacet(Facet::createTagFacet(m_facetWidget));
}
void Nepomuk::Utils::SearchWidget::SearchWidgetPrivate::_k_queryComponentChanged()
{
if ( !m_inQueryComponentChanged ) {
m_inQueryComponentChanged = true;
const Query::Query query = currentQuery();
if( query != m_currentQuery ) {
m_resourceModel->clear();
// TODO: show busy indicator
kDebug() << query;
m_queryClient.close();
if( query.isValid() ) {
m_queryClient.query(query);
}
m_facetWidget->setClientQuery(query);
m_currentQuery = query;
}
m_inQueryComponentChanged = false;
}
else {
// we need to handle all component changes since one may trigger another
QMetaObject::invokeMethod(q, "_k_queryComponentChanged", Qt::QueuedConnection);
}
}
void Nepomuk::Utils::SearchWidget::SearchWidgetPrivate::_k_listingFinished()
{
// TODO: disable busy indicator
}
void Nepomuk::Utils::SearchWidget::SearchWidgetPrivate::_k_forwardCurrentChanged(
const QModelIndex & previous, const QModelIndex & current )
{
Resource prevRes;
Resource currRes;
if ( previous.isValid() ) {
prevRes = previous.data(Utils::ResourceModel::ResourceRole).value<Resource>();
}
if ( current.isValid() ) {
currRes = current.data(Utils::ResourceModel::ResourceRole).value<Resource>();
}
emit q->currentResourceChanged(prevRes,currRes);
}
Nepomuk::Query::Query Nepomuk::Utils::SearchWidget::SearchWidgetPrivate::currentQuery( bool withBaseQuery ) const
{
Query::Query query;
if( withBaseQuery ) {
kDebug() << "************ baseQuery: " << m_baseQuery;
query = m_baseQuery;
}
Query::Term facetTerm = m_facetWidget->queryTerm();
Query::Term userQueryTerm = m_queryEdit->query().term();
kDebug() << "************ userQuery: " << userQueryTerm;
kDebug() << "************ facetQuery: " << facetTerm;
return query && facetTerm && userQueryTerm;
}
Nepomuk::Utils::SearchWidget::SearchWidget(QWidget *parent)
: QWidget(parent),
d_ptr(new SearchWidgetPrivate())
{
Q_D(SearchWidget);
d->q = this;
//query editor widget
d->m_queryEdit = new SearchLineEdit(this);
d->m_queryButton = new KPushButton(i18n("Search"), this);
connect(d->m_queryEdit, SIGNAL(queryChanged(Nepomuk::Query::Query)), this, SLOT(_k_queryComponentChanged()));
connect(d->m_queryButton, SIGNAL(clicked()), this, SLOT(_k_queryComponentChanged()));
//item widget
d->m_itemWidget = new QListView(this);
d->m_resourceModel = new Utils::SimpleResourceModel(this);
d->m_itemWidget->setModel(d->m_resourceModel);
connect(d->m_itemWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SIGNAL(selectionChanged()));
connect(d->m_itemWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this, SLOT(_k_forwardCurrentChanged(QModelIndex,QModelIndex)));
//facets widget
d->m_facetWidget = new Nepomuk::Utils::FacetWidget(this);
d->setupFacetWidget();
connect(d->m_facetWidget, SIGNAL(queryTermChanged(Nepomuk::Query::Term)), this, SLOT(_k_queryComponentChanged()));
//layout and config
QSplitter* facetSplitter = new QSplitter(this);
facetSplitter->addWidget(d->m_itemWidget);
facetSplitter->addWidget(d->m_facetWidget);
QGridLayout* layout = new QGridLayout( this );
layout->setMargin(0);
layout->addWidget( d->m_queryEdit, 0, 0 );
layout->addWidget( d->m_queryButton, 0, 1 );
layout->addWidget( facetSplitter, 1, 0, 1, 2 );
layout->setRowStretch(1,1);
// query client setup
connect( &d->m_queryClient, SIGNAL(newEntries(QList<Nepomuk::Query::Result>)),
d->m_resourceModel, SLOT(addResults(QList<Nepomuk::Query::Result>)) );
connect( &d->m_queryClient, SIGNAL(finishedListing()),
this, SLOT(_k_listingFinished()));
setSelectionMode(QListView::ExtendedSelection);
setConfigFlags( DefaultConfigFlags );
}
Nepomuk::Utils::SearchWidget::~SearchWidget()
{
delete d_ptr;
}
void Nepomuk::Utils::SearchWidget::setConfigFlags( ConfigFlags flags )
{
Q_D(SearchWidget);
d->m_configFlags = flags;
d->m_facetWidget->setShown( flags&ShowFacets );
d->m_queryButton->setShown( !( flags&SearchWhileYouType ) );
d->m_queryEdit->setSearchWhileTypingEnabled( flags&SearchWhileYouType );
}
Nepomuk::Utils::SearchWidget::ConfigFlags Nepomuk::Utils::SearchWidget::configFlags() const
{
Q_D(const SearchWidget);
return d->m_configFlags;
}
void Nepomuk::Utils::SearchWidget::setSelectionMode ( QAbstractItemView::SelectionMode mode )
{
Q_D(SearchWidget);
d->m_itemWidget->setSelectionMode(mode);
}
QAbstractItemView::SelectionMode Nepomuk::Utils::SearchWidget::selectionMode () const
{
Q_D(const SearchWidget);
return d->m_itemWidget->selectionMode();
}
Nepomuk::Query::Query Nepomuk::Utils::SearchWidget::setQuery( const Nepomuk::Query::Query &query )
{
Q_D(SearchWidget);
// try to extract as much as possible from the query as facets
Query::Query restQuery = d->m_facetWidget->extractFacetsFromQuery( query );
// try to get the rest into the line edit
restQuery.setTerm( d->m_queryEdit->extractUsableTerms( restQuery.term() ) );
return restQuery;
}
void Nepomuk::Utils::SearchWidget::setBaseQuery( const Query::Query& query )
{
Q_D(SearchWidget);
d->m_baseQuery = query;
d->_k_queryComponentChanged();
}
Nepomuk::Query::Query Nepomuk::Utils::SearchWidget::baseQuery() const
{
Q_D(const SearchWidget);
return d->m_baseQuery;
}
Nepomuk::Query::Query Nepomuk::Utils::SearchWidget::query() const
{
Q_D(const SearchWidget);
return d->currentQuery();
}
Nepomuk::Resource Nepomuk::Utils::SearchWidget::currentResource() const
{
Q_D(const SearchWidget);
return d->m_itemWidget->currentIndex().data(Utils::ResourceModel::ResourceRole).value<Resource>();
}
QList<Nepomuk::Resource> Nepomuk::Utils::SearchWidget::selectedResources() const
{
Q_D(const SearchWidget);
QList<Nepomuk::Resource> resourceList;
foreach(const QModelIndex& index, d->m_itemWidget->selectionModel()->selectedIndexes()) {
resourceList << index.data(Utils::ResourceModel::ResourceRole).value<Resource>();
}
return resourceList;
}
Nepomuk::Utils::FacetWidget* Nepomuk::Utils::SearchWidget::facetWidget() const
{
Q_D(const SearchWidget);
return d->m_facetWidget;
}
// static
Nepomuk::Resource Nepomuk::Utils::SearchWidget::searchResource( QWidget* parent,
const Nepomuk::Query::Query& baseQuery,
SearchWidget::ConfigFlags flags )
{
KDialog dlg( parent );
dlg.setButtons(KDialog::Ok | KDialog::Cancel);
SearchWidget* searchWidget = new SearchWidget(&dlg);
dlg.setMainWidget(searchWidget);
searchWidget->setBaseQuery( baseQuery );
searchWidget->setConfigFlags( flags );
searchWidget->setSelectionMode( QAbstractItemView::SingleSelection );
if( dlg.exec() == QDialog::Accepted ) {
return searchWidget->currentResource();
}
else {
return Nepomuk::Resource();
}
}
// static
QList<Nepomuk::Resource> Nepomuk::Utils::SearchWidget::searchResources( QWidget* parent,
const Nepomuk::Query::Query& baseQuery,
SearchWidget::ConfigFlags flags )
{
KDialog dlg( parent );
dlg.setButtons(KDialog::Ok | KDialog::Cancel);
SearchWidget* searchWidget = new SearchWidget(&dlg);
dlg.setMainWidget(searchWidget);
searchWidget->setBaseQuery( baseQuery );
searchWidget->setConfigFlags( flags );
searchWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
if( dlg.exec() == QDialog::Accepted ) {
return searchWidget->selectedResources();
}
else {
return QList<Nepomuk::Resource>();
}
}
#include "searchwidget.moc"