kde-playground/kdepim/messageviewer/viewer/mimetreemodel.cpp
2015-04-14 21:49:29 +00:00

257 lines
7.9 KiB
C++

/*
Copyright (c) 2007, 2008 Volker Krause <vkrause@kde.org>
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 "utils/util.h"
#include "mimetreemodel.h"
#include "nodehelper.h"
#include <kmime/kmime_content.h>
#include <KMime/Message>
#include <KDebug>
#include <KIcon>
#include <KLocalizedString>
#include <KMimeType>
Q_DECLARE_METATYPE(KMime::Content*)
Q_DECLARE_METATYPE(KMime::ContentIndex)
using namespace MessageViewer;
class MimeTreeModel::Private
{
public:
Private() :
root ( 0 )
{}
// FIXME: this should actually be a member function of ContentIndex
int contentIndexUp( KMime::ContentIndex &index )
{
Q_ASSERT( index.isValid() );
QStringList ids = index.toString().split( QLatin1Char('.') );
const QString lastId = ids.takeLast();
index = KMime::ContentIndex( ids.join( QLatin1String(".") ) );
return lastId.toInt();
}
QString descriptionForContent( KMime::Content *content )
{
KMime::Message * const message = dynamic_cast<KMime::Message*>( content );
if ( message && message->subject( false ) )
return message->subject()->asUnicodeString();
const QString name = NodeHelper::fileName( content );
if ( !name.isEmpty() )
return name;
if ( content->contentDescription( false ) ) {
const QString desc = content->contentDescription()->asUnicodeString();
if ( !desc.isEmpty() )
return desc;
}
return i18n( "body part" );
}
QString mimeTypeForContent( KMime::Content *content )
{
if ( content->contentType( false ) )
return QString::fromLatin1( content->contentType()->mimeType() );
return QString();
}
QString typeForContent( KMime::Content *content )
{
if ( content->contentType( false ) )
{
const QString contentMimeType = QString::fromLatin1(content->contentType()->mimeType());
KMimeType::Ptr mimeType = KMimeType::mimeType( contentMimeType );
if ( mimeType.isNull() )
return contentMimeType;
return mimeType->comment();
}
else
return QString();
}
QString sizeOfContent( KMime::Content *content )
{
if ( content->body().isEmpty() )
return QString();
return KGlobal::locale()->formatByteSize( content->body().size() );
}
KIcon iconForContent( KMime::Content *content )
{
if ( content->contentType( false ) )
{
KMimeType::Ptr mimeType = KMimeType::mimeType( QString::fromLatin1( content->contentType()->mimeType() ) );
if ( mimeType.isNull() || mimeType->name() == QLatin1String("application/octet-stream") ) {
const QString name = descriptionForContent(content);
mimeType = MessageViewer::Util::mimetype(name);
}
if ( mimeType.isNull() || mimeType->iconName().isEmpty() )
return KIcon();
if( mimeType->name().startsWith( QLatin1String( "multipart/" ) ) )
return KIcon( QLatin1String("folder") );
return KIcon( mimeType->iconName() );
}
else
return KIcon();
}
KMime::Content *root;
};
MimeTreeModel::MimeTreeModel(QObject * parent) :
QAbstractItemModel( parent ),
d ( new Private )
{
}
MimeTreeModel::~MimeTreeModel()
{
delete d;
}
void MimeTreeModel::setRoot(KMime::Content * root)
{
d->root = root;
reset();
}
KMime::Content* MimeTreeModel::root()
{
return d->root;
}
QModelIndex MimeTreeModel::index(int row, int column, const QModelIndex &parent) const
{
if ( !parent.isValid() ) {
if ( row != 0 )
return QModelIndex();
return createIndex( row, column, d->root );
}
KMime::Content *parentContent = static_cast<KMime::Content*>( parent.internalPointer() );
if ( !parentContent || parentContent->contents().count() <= row || row < 0 )
return QModelIndex();
KMime::Content *content = parentContent->contents().at( row );
return createIndex( row, column, content );
}
QModelIndex MimeTreeModel::parent(const QModelIndex & index) const
{
if ( !index.isValid() )
return QModelIndex();
KMime::Content *currentContent = static_cast<KMime::Content*>( index.internalPointer() );
if ( !currentContent )
return QModelIndex();
KMime::ContentIndex currentIndex = d->root->indexForContent( currentContent );
if ( !currentIndex.isValid() )
return QModelIndex();
d->contentIndexUp( currentIndex );
KMime::Content *parentContent = d->root->content( currentIndex );
int row = 0;
if ( currentIndex.isValid() )
row = d->contentIndexUp( currentIndex ) - 1; // 1 based -> 0 based
return createIndex( row, 0, parentContent );
}
int MimeTreeModel::rowCount(const QModelIndex & parent) const
{
if ( !d->root )
return 0;
if ( !parent.isValid() )
return 1;
KMime::Content *parentContent = static_cast<KMime::Content*>( parent.internalPointer() );
if ( parentContent )
return parentContent->contents().count();
return 0;
}
int MimeTreeModel::columnCount(const QModelIndex & parent) const
{
Q_UNUSED( parent );
return 3;
}
QVariant MimeTreeModel::data(const QModelIndex & index, int role) const
{
KMime::Content *content = static_cast<KMime::Content*>( index.internalPointer() );
if ( !content )
return QVariant();
if ( role == Qt::ToolTipRole ) {
// TODO
//return d->root->indexForContent( content ).toString();
return QVariant();
}
if ( role == Qt::DisplayRole ) {
switch( index.column() ) {
case 0:
return d->descriptionForContent( content );
case 1:
return d->typeForContent( content );
case 2:
return d->sizeOfContent( content );
}
}
if ( role == Qt::DecorationRole && index.column() == 0 ) {
return d->iconForContent( content );
}
if ( role == ContentIndexRole )
return QVariant::fromValue( d->root->indexForContent( content ) );
if ( role == ContentRole )
return QVariant::fromValue( content );
if ( role == MimeTypeRole )
return d->mimeTypeForContent( content );
if ( role == MainBodyPartRole ) {
KMime::Message* topLevelMsg = dynamic_cast<KMime::Message*>( d->root );
if ( !topLevelMsg )
return false;
return topLevelMsg->mainBodyPart() == content;
}
if ( role == AlternativeBodyPartRole ) {
KMime::Message* topLevelMsg = dynamic_cast<KMime::Message*>( d->root );
if ( !topLevelMsg )
return false;
return topLevelMsg->mainBodyPart( content->contentType()->mimeType() ) == content;
}
return QVariant();
}
QVariant MimeTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) {
switch ( section ) {
case 0:
return i18n( "Description" );
case 1:
return i18n( "Type" );
case 2:
return i18n( "Size" );
}
}
return QAbstractItemModel::headerData( section, orientation, role );
}