kde-playground/kdepim/calendarsupport/incidenceattachmentmodel.cpp
2015-04-14 21:49:29 +00:00

220 lines
6.3 KiB
C++

/*
Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Stephen Kelly <stephen@kdab.com>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
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 Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "incidenceattachmentmodel.h"
#include <Akonadi/EntityTreeModel>
#include <Akonadi/ItemFetchJob>
#include <Akonadi/ItemFetchScope>
#include <Akonadi/Monitor>
using namespace CalendarSupport;
using namespace Akonadi;
namespace CalendarSupport {
class IncidenceAttachmentModelPrivate
{
IncidenceAttachmentModelPrivate( IncidenceAttachmentModel *qq,
const QPersistentModelIndex &modelIndex,
Akonadi::Item item = Akonadi::Item() )
: q_ptr( qq ), m_modelIndex( modelIndex ), m_item( item ), m_monitor( 0 )
{
if ( modelIndex.isValid() ) {
QObject::connect( modelIndex.model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
qq, SLOT(resetModel()) );
} else if ( item.isValid() ) {
createMonitor();
resetInternalData();
}
QHash<int, QByteArray> roleNames = qq->roleNames();
roleNames.insert( IncidenceAttachmentModel::MimeTypeRole, "mimeType" );
roleNames.insert( IncidenceAttachmentModel::AttachmentUrl, "attachmentUrl" );
qq->setRoleNames( roleNames );
}
void resetModel()
{
Q_Q( IncidenceAttachmentModel );
q->beginResetModel();
resetInternalData();
q->endResetModel();
emit q->rowCountChanged();
}
void itemFetched( Akonadi::Item::List list )
{
Q_ASSERT( list.size() == 1 );
setItem( list.first() );
}
void setItem( const Akonadi::Item &item );
void createMonitor()
{
if ( m_monitor ) {
return;
}
m_monitor = new Akonadi::Monitor( q_ptr );
m_monitor->setItemMonitored( m_item );
m_monitor->itemFetchScope().fetchFullPayload( true );
QObject::connect( m_monitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
q_ptr, SLOT(resetModel()) );
QObject::connect( m_monitor, SIGNAL(itemRemoved(Akonadi::Item)),
q_ptr, SLOT(resetModel()) );
}
void resetInternalData()
{
if ( m_incidence ) {
m_incidence->clearTempFiles();
}
Item item = m_item;
if ( m_modelIndex.isValid() ) {
item = m_modelIndex.data( EntityTreeModel::ItemRole ).value<Akonadi::Item>();
}
if ( !item.isValid() || !item.hasPayload<KCalCore::Incidence::Ptr>() ) {
m_incidence = KCalCore::Incidence::Ptr();
return;
}
m_incidence = item.payload<KCalCore::Incidence::Ptr>();
}
Q_DECLARE_PUBLIC( IncidenceAttachmentModel )
IncidenceAttachmentModel * const q_ptr;
QModelIndex m_modelIndex;
Akonadi::Item m_item;
KCalCore::Incidence::Ptr m_incidence;
Akonadi::Monitor *m_monitor;
};
}
IncidenceAttachmentModel::IncidenceAttachmentModel( const QPersistentModelIndex &modelIndex,
QObject *parent )
: QAbstractListModel( parent ),
d_ptr( new IncidenceAttachmentModelPrivate( this, modelIndex ) )
{
}
IncidenceAttachmentModel::IncidenceAttachmentModel( const Akonadi::Item &item, QObject *parent )
: QAbstractListModel( parent ),
d_ptr( new IncidenceAttachmentModelPrivate( this, QModelIndex(), item ) )
{
}
IncidenceAttachmentModel::IncidenceAttachmentModel( QObject *parent )
: QAbstractListModel( parent ),
d_ptr( new IncidenceAttachmentModelPrivate( this, QModelIndex() ) )
{
}
IncidenceAttachmentModel::~IncidenceAttachmentModel()
{
delete d_ptr;
}
KCalCore::Incidence::Ptr IncidenceAttachmentModel::incidence() const
{
Q_D( const IncidenceAttachmentModel );
return d->m_incidence;
}
void IncidenceAttachmentModel::setIndex( const QPersistentModelIndex &modelIndex )
{
Q_D( IncidenceAttachmentModel );
beginResetModel();
d->m_modelIndex = modelIndex;
d->m_item = Akonadi::Item();
d->resetInternalData();
endResetModel();
emit rowCountChanged();
}
void IncidenceAttachmentModel::setItem( const Akonadi::Item &item )
{
Q_D( IncidenceAttachmentModel );
if ( !item.hasPayload<KCalCore::Incidence::Ptr>() ) {
ItemFetchJob *job = new ItemFetchJob( item );
job->fetchScope().fetchFullPayload( true );
connect( job, SIGNAL(itemsReceived(Akonadi::Item::List)),
SLOT(itemFetched(Akonadi::Item::List)) );
return;
}
d->setItem( item );
}
void IncidenceAttachmentModelPrivate::setItem( const Akonadi::Item &item )
{
Q_Q( IncidenceAttachmentModel );
q->beginResetModel();
m_modelIndex = QModelIndex();
m_item = item;
createMonitor();
resetInternalData();
q->endResetModel();
emit q->rowCountChanged();
}
int IncidenceAttachmentModel::rowCount( const QModelIndex & ) const
{
Q_D( const IncidenceAttachmentModel );
if ( !d->m_incidence ) {
return 0;
} else {
return d->m_incidence->attachments().size();
}
}
QVariant IncidenceAttachmentModel::data( const QModelIndex &index, int role ) const
{
Q_D( const IncidenceAttachmentModel );
if ( !d->m_incidence ) {
return QVariant();
}
KCalCore::Attachment::Ptr attachment = d->m_incidence->attachments().at( index.row() );
switch ( role ) {
case Qt::DisplayRole:
return attachment->label();
case AttachmentDataRole:
return attachment->decodedData();
case MimeTypeRole:
return attachment->mimeType();
case AttachmentUrl:
return d->m_incidence->writeAttachmentToTempFile( attachment );
}
return QVariant();
}
QVariant IncidenceAttachmentModel::headerData( int section,
Qt::Orientation orientation,
int role ) const
{
return QAbstractItemModel::headerData( section, orientation, role );
}
#include "moc_incidenceattachmentmodel.cpp"