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