I could not help myself and implemented a little bit. My idea is to have
the model populate itself with facets (not implemented).
I do not really see an advantage in subclassing yet.
A plain design like mine allows for things like facet serialization
which might come in handy for query URLs in nepomuksearch:/.
Also there is no need for special handling of any kind of facet. Of
course that could also be achieved with subclassing.
However, there are some things that are similar in all types of facets
anyway like the frequency querying.
Anyway, I think that the model design I propose would be compatible with
subclassing facets, too.

Cheers,
Sebastian

On 06/25/2010 06:51 PM, Alessandro Sivieri wrote:
> Well, here is a thought: in my current classes, I subclass Facet for
> each facet I want to add to the side panel; in your classes, there
> should be an external manager creating them, because if we want the
> subclassing thing we need Facet to subclass QObject (at least for the
> Term creation with their parent parameter); so the manager itself will
> have the queries loading the items...
> 
> -- 
> Sivieri Alessandro
> [email protected] <mailto:[email protected]>
> http://www.chimera-bellerofonte.eu/
> http://www.poul.org/
/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2010 Sebastian Trueg <[email protected]>

   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 "facetmodel.h"
#include "facet.h"

#include <QtCore/QHash>


class Nepomuk::Query::FacetModel::FacetModelPrivate
{
public:
    QList<Facet> m_facets;
    QHash<Facet, QList<int> > m_selectedTerms;
};


Nepomuk::Query::FacetModel::FacetModel( QObject* parent )
    : QAbstractItemModel( parent ),
      d(new FacetModelPrivate() )
{
}


Nepomuk::Query::FacetModel::~FacetModel()
{
    delete d;
}


int Nepomuk::Query::FacetModel::columnCount( const QModelIndex& parent ) const
{
    return 1;
}


QVariant Nepomuk::Query::FacetModel::data( const QModelIndex& index, int role ) const
{
    if( index.isValid() ) {
        if( index.internalPointer() ) {
            Facet* facet = static_cast<Facet*>( index.internalPointer() );
            switch( role ) {
            case Qt::DisplayRole:
                return facet->titleAt(index.row());
            case Qt::CheckStateRole:
                return( d->m_selectedTerms[*facet].contains(index.row()) ? Qt::Checked : Qt::Unchecked );
            }
        }
        else {
            switch( role ) {
            case Qt::DisplayRole:
                return d->m_facets[index.row()].title();
            }
        }
    }

    return QVariant();
}


bool Nepomuk::Query::FacetModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
    if( role == Qt::CheckStateRole &&
        index.internalPointer() ) {
        Facet* facet = static_cast<Facet*>( index.internalPointer() );
        QList<int>& termIndexes = d->m_selectedTerms[*facet];
        if( facet->exclusive() ) {
            // we ignore the value as you cannot uncheck an item in exclusive mode
            termIndexes.clear();
            termIndexes.append( index.row() );
        }
        else {
            if( value.toBool() )
                termIndexes.append( index.row() );
            else
                termIndexes.removeAll( index.row() );
        }
        emit facetsChanged();
        return true;
    }
    else {
        return false;
    }
}


QModelIndex Nepomuk::Query::FacetModel::parent( const QModelIndex& index ) const
{
    if( index.internalPointer() ) {
        Facet* facet = static_cast<Facet*>( index.internalPointer() );
        return createIndex( d->m_facets.indexOf(*facet), 0 );
    }
    else {
        return QModelIndex();
    }
}


int Nepomuk::Query::FacetModel::rowCount( const QModelIndex& parent ) const
{
    if( !parent.isValid() ) {
        return d->m_facets.count();
    }
    else if( parent.row() < d->m_facets.count() ) {
        return d->m_facets[parent.row()].count();
    }
    else {
        return 0;
    }
}


QModelIndex Nepomuk::Query::FacetModel::index( int row, int column, const QModelIndex& parent ) const
{
    if( parent.isValid() ) {
        return createIndex( row, column, &d->m_facets[parent.row()] );
    }
    else {
        return createIndex( row, column );
    }
}


Qt::ItemFlags Nepomuk::Query::FacetModel::flags( const QModelIndex& index ) const
{
    // we do not even allow selection since that does not make much sense for our use case
    Qt::ItemFlags flags = Qt::ItemIsEnabled;
    if( index.internalPointer() ) {
        flags |= Qt::ItemIsUserCheckable;
    }
    return flags;
}


void Nepomuk::Query::FacetModel::addFacet( const Facet& facet )
{
    d->m_facets.append(facet);
    QList<int> selected;
    if(facet.exclusive())
        selected << 0;
    d->m_selectedTerms.insert(facet, selected);
    reset();
    emit facetsChanged();
    // TODO: do not use reset but the fancy begin/end methods
}


void Nepomuk::Query::FacetModel::clear()
{
    d->m_facets.clear();
    d->m_selectedTerms.clear();
    reset();
}


QList<Nepomuk::Query::Facet> Nepomuk::Query::FacetModel::facets() const
{
    return d->m_facets;
}


QList<Nepomuk::Query::Term> Nepomuk::Query::FacetModel::selectedTerms() const
{
    QList<Nepomuk::Query::Term> terms;
    Q_FOREACH(const Facet& facet, d->m_facets) {
        Q_FOREACH(int i, d->m_selectedTerms[facet]) {
            terms.append( facet.termAt(i) );
        }
    }
    return terms;
}


Nepomuk::Query::Query Nepomuk::Query::FacetModel::constructQuery( const Query& baseQuery ) const
{
}


Nepomuk::Query::Query Nepomuk::Query::FacetModel::extractFacetsFromQuery( const Query& query )
{
}


void Nepomuk::Query::FacetModel::populateFromQuery( const Query& query )
{
    // TODO: create facets for datetime, priority, document type, tags, and later the automatic one or a rule-based one which handles artists and authors and that sort of thing
    // TODO: do not delete all existing facets but instead reset them accordingly.
}

#include "facetmodel.moc"
/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2010 Sebastian Trueg <[email protected]>

   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/>.
*/

#ifndef _NEPOMUK_QUERY_FACET_MODEL_H_
#define _NEPOMUK_QUERY_FACET_MODEL_H_

#include "nepomukquery_export.h"

#include "query.h"
#include "term.h"

#include <QtCore/QAbstractItemModel>
#include <QtCore/QList>

namespace Nepomuk {
    namespace Query {
        class Facet;

        /**
         * A FacetModel contains a list of facets that are provided in a tree
         * structure.
         */
        class NEPOMUKQUERY_EXPORT FacetModel : public QAbstractItemModel
        {
            Q_OBJECT

        public:
            FacetModel( QObject* parent = 0 );
            ~FacetModel();

            int columnCount( const QModelIndex& parent = QModelIndex() ) const;
            QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
            bool setData( const QModelIndex& index, const QVariant& value, int role );
            QModelIndex parent( const QModelIndex& index ) const;
            int rowCount( const QModelIndex& parent = QModelIndex() ) const;
            QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const;
            Qt::ItemFlags flags( const QModelIndex& index ) const;

            void addFacet( const Facet& facet );
            void clear();

            QList<Facet> facets() const;

            QList<Term> selectedTerms() const;

            /**
             * Construct a query from the selected facets in this model and \p baseQuery.
             *
             * \return A new query which combines the facets in this model with \p baseQuery.
             */
            Query constructQuery( const Query& baseQuery = Query() ) const;

            /**
             * Extract as many facets from a query as possible. This method is not able to handle all
             * kinds of queries but works well on queries created via constructQuery().
             *
             * Facets supported by this model will be extracted from the \p query and configured
             * accordingly in the model.
             *
             * \return A new query which combined with the facets in this model will result in \p query
             * again.
             */
            Query extractFacetsFromQuery( const Query& query );

        Q_SIGNALS:
            void facetsChanged();

        public Q_SLOTS:
            /**
             * Automatically create facets for the given query.
             */
            void populateFromQuery( const Query& query );

        private:
            class FacetModelPrivate;
            FacetModelPrivate* const d;
        };
    }
}

#endif
/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2010 Sebastian Trueg <[email protected]>

   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/>.
*/

#ifndef _NEPOMUK_QUERY_FACET_H_
#define _NEPOMUK_QUERY_FACET_H_

#include <QtCore/QVariant>
#include <QtCore/QList>
#include <QtCore/QSharedDataPointer>

#include "term.h"

#include "nepomukquery_export.h"

class QString;

namespace Nepomuk {
    namespace Query {
        class Query;

        class NEPOMUKQUERY_EXPORT Facet
        {
        public:
            Facet();
            Facet( const Facet& other );
            ~Facet();

            Facet& operator=( const Facet& other );

            QString title() const;
            bool exclusive() const;
            QString rangeTitle() const;
            QVariant::Type rangeType() const;

            void setTitle( const QString& title );
            void setExclusive( bool exclusive );

            /**
             * Allows to set a custom title for the first entry in the
             * facet selection. Defaults to "None". Be aware that the
             * no selection term is only used for exclusive() facets.
             *
             * \sa setNoSelectionTerm()
             */
            void setNoSelectionTitle( const QString& title );

            /**
             * Allows to customize the term of the first entry. Be aware
             * that the no selection term is only used for exclusive() facets.
             *
             * \sa setNoSelectionTitle()
             */
            void setNoSelectionTerm( const Term& term );

            /**
             * Especially dates are better expressed in ranges.
             * While a group normally only contains fixed Facets
             * the range type allows to provide a user selection
             * of the range in which the facet should result.
             *
             * By default the type is invalid which means that
             * no range is available.
             */
            void setRangeType( QVariant::Type );

            /**
             * Set the title displayed to the user when offering GUI
             * for the range selection.
             */
            void setRangeTitle( const QString& title );

            /**
             * Used by the GUI to set the user selected range. The corresponding
             * term can be created via createRangeTerm(). This avoids caching the
             * values in the GUI classes.
             */
            void setRange( const QVariant& start, const QVariant& end );

            /**
             * Used by the GUI to create the term for a range selected by the user.
             */
            Term createRangeTerm() const;

            void addTerm( const Term& term, const QString& title );
            void clear();

            /**
             * The number of terms in the facet. This includes the no selection term
             * (in case the facet is exclusive) and the optional range term.
             */
            int count() const;

            Term termAt( int i ) const;
            QString titleAt( int i ) const;
            QString termTitle( const Term& term ) const;

            QList<Term> termList() const;

            bool operator==( const Facet& other ) const;
            bool operator!=( const Facet& other ) const;

        private:
            class FacetPrivate;
            QSharedDataPointer<FacetPrivate> d;
        };

        NEPOMUKQUERY_EXPORT uint qHash( const Facet& facet );
    }
}

#endif
/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2010 Sebastian Trueg <[email protected]>

   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 "facet.h"

#include <QtCore/QSharedData>


class Nepomuk::Query::Facet::FacetPrivate : public QSharedData
{
public:
};


Nepomuk::Query::Facet::Facet()
    : d(new FacetPrivate())
{
}


Nepomuk::Query::Facet::Facet( const Facet& other )
{
    d = other.d;
}


Nepomuk::Query::Facet::~Facet()
{
}


Nepomuk::Query::Facet& Nepomuk::Query::Facet::operator=( const Facet& other )
{
    d = other.d;
    return *this;
}


QString Nepomuk::Query::Facet::title() const
{
}


bool Nepomuk::Query::Facet::exclusive() const
{
}


QString Nepomuk::Query::Facet::rangeTitle() const
{
}


QVariant::Type Nepomuk::Query::Facet::rangeType() const
{
}


void Nepomuk::Query::Facet::setTitle( const QString& title )
{
}


void Nepomuk::Query::Facet::setExclusive( bool exclusive )
{
}


void Nepomuk::Query::Facet::setNoSelectionTitle( const QString& title )
{
}


void Nepomuk::Query::Facet::setNoSelectionTerm( const Term& term )
{
}


void Nepomuk::Query::Facet::setRangeType( QVariant::Type )
{
}


void Nepomuk::Query::Facet::setRangeTitle( const QString& title )
{
}


void Nepomuk::Query::Facet::setRange( const QVariant& start, const QVariant& end )
{
}


Nepomuk::Query::Term Nepomuk::Query::Facet::createRangeTerm() const
{
}


void Nepomuk::Query::Facet::addTerm( const Term& term, const QString& title )
{
}


void Nepomuk::Query::Facet::clear()
{
}


int Nepomuk::Query::Facet::count() const
{
}


Nepomuk::Query::Term Nepomuk::Query::Facet::termAt( int i ) const
{
}


QString Nepomuk::Query::Facet::titleAt( int i ) const
{
}


QString Nepomuk::Query::Facet::termTitle( const Term& term ) const
{
}


QList<Nepomuk::Query::Term> Nepomuk::Query::Facet::termList() const
{
}


bool Nepomuk::Query::Facet::operator==( const Facet& other ) const
{
}


bool Nepomuk::Query::Facet::operator!=( const Facet& other ) const
{
}


uint Nepomuk::Query::qHash( const Facet& facet )
{
}
_______________________________________________
Nepomuk mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/nepomuk

Reply via email to