It provides the items this way: root + page 1 | + annotations for page 1 + page 2 | + annotations for page 2 .. and so on It does not return subtrees for pages without annotations. svn path=/trunk/KDE/kdegraphics/okular/; revision=709946remotes/origin/KDE/4.0
parent
73329a23cf
commit
239434362e
3 changed files with 304 additions and 0 deletions
@ -0,0 +1,248 @@ |
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2006 by Pino Toscano <pino@kde.org> * |
||||||
|
* * |
||||||
|
* 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. * |
||||||
|
***************************************************************************/ |
||||||
|
|
||||||
|
#include "annotationmodel.h" |
||||||
|
|
||||||
|
#include <qlinkedlist.h> |
||||||
|
#include <qlist.h> |
||||||
|
|
||||||
|
#include <kicon.h> |
||||||
|
|
||||||
|
#include "core/annotations.h" |
||||||
|
#include "core/document.h" |
||||||
|
#include "core/observer.h" |
||||||
|
#include "core/page.h" |
||||||
|
|
||||||
|
struct AnnotationItem |
||||||
|
{ |
||||||
|
AnnotationItem(); |
||||||
|
AnnotationItem( AnnotationItem *parent, Okular::Annotation *ann ); |
||||||
|
AnnotationItem( AnnotationItem *parent, int page ); |
||||||
|
~AnnotationItem(); |
||||||
|
|
||||||
|
AnnotationItem *parent; |
||||||
|
QList< AnnotationItem* > children; |
||||||
|
|
||||||
|
Okular::Annotation *annotation; |
||||||
|
int page; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
class AnnotationModelPrivate : public Okular::DocumentObserver |
||||||
|
{ |
||||||
|
public: |
||||||
|
AnnotationModelPrivate( AnnotationModel *qq ); |
||||||
|
virtual ~AnnotationModelPrivate(); |
||||||
|
|
||||||
|
virtual uint observerId() const; |
||||||
|
virtual void notifySetup( const QVector< Okular::Page * > &pages, bool documentChanged ); |
||||||
|
|
||||||
|
QModelIndex indexForItem( AnnotationItem *item ) const; |
||||||
|
void rebuildTree( const QVector< Okular::Page * > &pages ); |
||||||
|
|
||||||
|
AnnotationModel *q; |
||||||
|
AnnotationItem *root; |
||||||
|
Okular::Document *document; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
AnnotationItem::AnnotationItem() |
||||||
|
: parent( 0 ), annotation( 0 ), page( -1 ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
AnnotationItem::AnnotationItem( AnnotationItem *_parent, Okular::Annotation *ann ) |
||||||
|
: parent( _parent ), annotation( ann ), page( _parent->page ) |
||||||
|
{ |
||||||
|
Q_ASSERT( !parent->annotation ); |
||||||
|
parent->children.append( this ); |
||||||
|
} |
||||||
|
|
||||||
|
AnnotationItem::AnnotationItem( AnnotationItem *_parent, int _page ) |
||||||
|
: parent( _parent ), annotation( 0 ), page( _page ) |
||||||
|
{ |
||||||
|
Q_ASSERT( !parent->parent ); |
||||||
|
parent->children.append( this ); |
||||||
|
} |
||||||
|
|
||||||
|
AnnotationItem::~AnnotationItem() |
||||||
|
{ |
||||||
|
qDeleteAll( children ); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
AnnotationModelPrivate::AnnotationModelPrivate( AnnotationModel *qq ) |
||||||
|
: q( qq ), root( new AnnotationItem ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
AnnotationModelPrivate::~AnnotationModelPrivate() |
||||||
|
{ |
||||||
|
delete root; |
||||||
|
} |
||||||
|
|
||||||
|
uint AnnotationModelPrivate::observerId() const |
||||||
|
{ |
||||||
|
return ANNOTATIONMODEL_ID; |
||||||
|
} |
||||||
|
|
||||||
|
void AnnotationModelPrivate::notifySetup( const QVector< Okular::Page * > &pages, bool documentChanged ) |
||||||
|
{ |
||||||
|
if ( !documentChanged ) |
||||||
|
return; |
||||||
|
|
||||||
|
qDeleteAll( root->children ); |
||||||
|
root->children.clear(); |
||||||
|
q->reset(); |
||||||
|
|
||||||
|
rebuildTree( pages ); |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex AnnotationModelPrivate::indexForItem( AnnotationItem *item ) const |
||||||
|
{ |
||||||
|
if ( item->parent ) |
||||||
|
{ |
||||||
|
int id = item->parent->children.indexOf( item ); |
||||||
|
if ( id >= 0 && id < item->parent->children.count() ) |
||||||
|
return q->createIndex( id, 0, item ); |
||||||
|
} |
||||||
|
return QModelIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
void AnnotationModelPrivate::rebuildTree( const QVector< Okular::Page * > &pages ) |
||||||
|
{ |
||||||
|
emit q->layoutAboutToBeChanged(); |
||||||
|
for ( int i = 0; i < pages.count(); ++i ) |
||||||
|
{ |
||||||
|
QLinkedList< Okular::Annotation* > annots = pages.at( i )->annotations(); |
||||||
|
if ( annots.isEmpty() ) |
||||||
|
continue; |
||||||
|
|
||||||
|
AnnotationItem *annItem = new AnnotationItem( root, i ); |
||||||
|
QLinkedList< Okular::Annotation* >::ConstIterator it = annots.begin(), itEnd = annots.end(); |
||||||
|
for ( ; it != itEnd; ++it ) |
||||||
|
{ |
||||||
|
new AnnotationItem( annItem, *it ); |
||||||
|
} |
||||||
|
} |
||||||
|
emit q->layoutChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
AnnotationModel::AnnotationModel( Okular::Document *document, QObject *parent ) |
||||||
|
: QAbstractItemModel( parent ), d( new AnnotationModelPrivate( this ) ) |
||||||
|
{ |
||||||
|
d->document = document; |
||||||
|
|
||||||
|
d->document->addObserver( d ); |
||||||
|
} |
||||||
|
|
||||||
|
AnnotationModel::~AnnotationModel() |
||||||
|
{ |
||||||
|
delete d; |
||||||
|
} |
||||||
|
|
||||||
|
int AnnotationModel::columnCount( const QModelIndex &parent ) const |
||||||
|
{ |
||||||
|
Q_UNUSED( parent ) |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant AnnotationModel::data( const QModelIndex &index, int role ) const |
||||||
|
{ |
||||||
|
if ( !index.isValid() ) |
||||||
|
return QVariant(); |
||||||
|
|
||||||
|
AnnotationItem *item = static_cast< AnnotationItem* >( index.internalPointer() ); |
||||||
|
if ( !item->annotation ) |
||||||
|
{ |
||||||
|
if ( role == Qt::DisplayRole ) |
||||||
|
return item->page; |
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
switch ( role ) |
||||||
|
{ |
||||||
|
case Qt::DisplayRole: |
||||||
|
return item->annotation->author(); |
||||||
|
break; |
||||||
|
case Qt::DecorationRole: |
||||||
|
return KIcon( "okular" ); |
||||||
|
break; |
||||||
|
case AuthorRole: |
||||||
|
return item->annotation->author(); |
||||||
|
break; |
||||||
|
case PageRole: |
||||||
|
return item->page; |
||||||
|
break; |
||||||
|
} |
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
|
||||||
|
bool AnnotationModel::hasChildren( const QModelIndex &parent ) const |
||||||
|
{ |
||||||
|
if ( !parent.isValid() ) |
||||||
|
return true; |
||||||
|
|
||||||
|
AnnotationItem *item = static_cast< AnnotationItem* >( parent.internalPointer() ); |
||||||
|
return !item->children.isEmpty(); |
||||||
|
} |
||||||
|
|
||||||
|
QVariant AnnotationModel::headerData( int section, Qt::Orientation orientation, int role ) const |
||||||
|
{ |
||||||
|
if ( orientation != Qt::Horizontal ) |
||||||
|
return QVariant(); |
||||||
|
|
||||||
|
if ( section == 0 && role == Qt::DisplayRole ) |
||||||
|
return "Annotations"; |
||||||
|
|
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex AnnotationModel::index( int row, int column, const QModelIndex &parent ) const |
||||||
|
{ |
||||||
|
if ( row < 0 || column != 0 ) |
||||||
|
return QModelIndex(); |
||||||
|
|
||||||
|
AnnotationItem *item = parent.isValid() ? static_cast< AnnotationItem* >( parent.internalPointer() ) : d->root; |
||||||
|
if ( row < item->children.count() ) |
||||||
|
return createIndex( row, column, item->children.at( row ) ); |
||||||
|
|
||||||
|
return QModelIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex AnnotationModel::parent( const QModelIndex &index ) const |
||||||
|
{ |
||||||
|
if ( !index.isValid() ) |
||||||
|
return QModelIndex(); |
||||||
|
|
||||||
|
AnnotationItem *item = static_cast< AnnotationItem* >( index.internalPointer() ); |
||||||
|
return d->indexForItem( item->parent ); |
||||||
|
} |
||||||
|
|
||||||
|
int AnnotationModel::rowCount( const QModelIndex &parent ) const |
||||||
|
{ |
||||||
|
AnnotationItem *item = parent.isValid() ? static_cast< AnnotationItem* >( parent.internalPointer() ) : d->root; |
||||||
|
return item->children.count(); |
||||||
|
} |
||||||
|
|
||||||
|
bool AnnotationModel::isAnnotation( const QModelIndex &index ) const |
||||||
|
{ |
||||||
|
return annotationForIndex( index ); |
||||||
|
} |
||||||
|
|
||||||
|
Okular::Annotation* AnnotationModel::annotationForIndex( const QModelIndex &index ) const |
||||||
|
{ |
||||||
|
if ( !index.isValid() ) |
||||||
|
return 0; |
||||||
|
|
||||||
|
AnnotationItem *item = static_cast< AnnotationItem* >( index.internalPointer() ); |
||||||
|
return item->annotation; |
||||||
|
} |
||||||
|
|
||||||
|
#include "annotationmodel.moc" |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2006 by Pino Toscano <pino@kde.org> * |
||||||
|
* * |
||||||
|
* 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. * |
||||||
|
***************************************************************************/ |
||||||
|
|
||||||
|
#ifndef ANNOTATIONMODEL_H |
||||||
|
#define ANNOTATIONMODEL_H |
||||||
|
|
||||||
|
#include <qabstractitemmodel.h> |
||||||
|
|
||||||
|
namespace Okular { |
||||||
|
class Annotation; |
||||||
|
class Document; |
||||||
|
} |
||||||
|
|
||||||
|
class AnnotationModelPrivate; |
||||||
|
|
||||||
|
class AnnotationModel : public QAbstractItemModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
public: |
||||||
|
enum { |
||||||
|
AuthorRole = Qt::UserRole + 1000, |
||||||
|
PageRole |
||||||
|
}; |
||||||
|
|
||||||
|
AnnotationModel( Okular::Document *document, QObject *parent = 0 ); |
||||||
|
virtual ~AnnotationModel(); |
||||||
|
|
||||||
|
// reimplementations from QAbstractItemModel
|
||||||
|
virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const; |
||||||
|
virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; |
||||||
|
virtual bool hasChildren( const QModelIndex &parent = QModelIndex() ) const; |
||||||
|
virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; |
||||||
|
virtual QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const; |
||||||
|
virtual QModelIndex parent( const QModelIndex &index ) const; |
||||||
|
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const; |
||||||
|
|
||||||
|
bool isAnnotation( const QModelIndex &index ) const; |
||||||
|
Okular::Annotation* annotationForIndex( const QModelIndex &index ) const; |
||||||
|
|
||||||
|
private: |
||||||
|
// storage
|
||||||
|
friend class AnnotationModelPrivate; |
||||||
|
AnnotationModelPrivate *const d; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue