You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
7.3 KiB
232 lines
7.3 KiB
/* -*- mode: C++; c-file-style: "gnu" -*- |
|
* |
|
* This file is part of KMail, the KDE mail client. |
|
* Copyright (c) 2003 Carsten Burghardt <burghardt@kde.org> |
|
* |
|
* KMail is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License, version 2, as |
|
* published by the Free Software Foundation. |
|
* |
|
* KMail 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 |
|
* General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License along |
|
* with this program; if not, write to the Free Software Foundation, Inc., |
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
* |
|
* In addition, as a special exception, the copyright holders give |
|
* permission to link the code of this program with any edition of |
|
* the Qt library by Trolltech AS, Norway (or with modified versions |
|
* of Qt that use the same license as Qt), and distribute linked |
|
* combinations including the two. You must obey the GNU General |
|
* Public License in all respects for all of the code used other than |
|
* Qt. If you modify this file, you may extend this exception to |
|
* your version of the file, but you are not obligated to do so. If |
|
* you do not wish to do so, delete this exception statement from |
|
* your version. |
|
*/ |
|
#include "bodyvisitor.h" |
|
#include "kmmsgpart.h" |
|
#include "attachmentstrategy.h" |
|
#include <kdebug.h> |
|
|
|
using namespace KMail; |
|
|
|
BodyVisitor *BodyVisitorFactory::getVisitor( const AttachmentStrategy *strategy ) |
|
{ |
|
if ( strategy == AttachmentStrategy::smart() ) { |
|
return new BodyVisitorSmart(); |
|
} else if ( strategy == AttachmentStrategy::iconic() ) { |
|
return new BodyVisitorHidden(); |
|
} else if ( strategy == AttachmentStrategy::inlined() ) { |
|
return new BodyVisitorInline(); |
|
} else if ( strategy == AttachmentStrategy::hidden()) { |
|
return new BodyVisitorHidden(); |
|
} |
|
// default |
|
return new BodyVisitorSmart(); |
|
} |
|
|
|
//============================================================================= |
|
|
|
BodyVisitor::BodyVisitor() |
|
{ |
|
// parts that are probably always ok to load |
|
mBasicList.clear(); |
|
// body text |
|
mBasicList += "TEXT/PLAIN"; |
|
mBasicList += "TEXT/HTML"; |
|
mBasicList += "MESSAGE/DELIVERY-STATUS"; |
|
// pgp stuff |
|
mBasicList += "APPLICATION/PGP-SIGNATURE"; |
|
mBasicList += "APPLICATION/PGP"; |
|
mBasicList += "APPLICATION/PGP-ENCRYPTED"; |
|
mBasicList += "APPLICATION/PKCS7-SIGNATURE"; |
|
// groupware |
|
mBasicList += "APPLICATION/MS-TNEF"; |
|
mBasicList += "TEXT/CALENDAR"; |
|
mBasicList += "TEXT/X-VCARD"; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
BodyVisitor::~BodyVisitor() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void BodyVisitor::visit( KMMessagePart *part ) |
|
{ |
|
mParts.append( part ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void BodyVisitor::visit( QList<KMMessagePart*> &list ) |
|
{ |
|
mParts = list; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
QList<KMMessagePart*> BodyVisitor::partsToLoad() |
|
{ |
|
QList<KMMessagePart*>::const_iterator it; |
|
QList<KMMessagePart*> selected; |
|
bool headerCheck = false; |
|
for ( it = mParts.begin(); it != mParts.end(); ++it ) { |
|
KMMessagePart *part = (*it); |
|
// skip this part if the parent part is already loading |
|
if ( part->parent() && |
|
selected.contains( part->parent() ) && |
|
part->loadPart() ) { |
|
continue; |
|
} |
|
|
|
if ( part->originalContentTypeStr().contains("SIGNED") ) { |
|
// signed messages have to be loaded completely |
|
// so construct a new dummy part that loads the body |
|
KMMessagePart *fake = new KMMessagePart(); |
|
fake->setPartSpecifier( "TEXT" ); |
|
fake->setOriginalContentTypeStr(""); |
|
fake->setLoadPart( true ); |
|
selected.append( fake ); |
|
break; |
|
} |
|
|
|
if ( headerCheck && !part->partSpecifier().endsWith(".HEADER") ) { |
|
// this is an embedded simple message (not multipart) so we get |
|
// no header part from imap. As we probably need to load the header |
|
// (e.g. in smart or inline mode) we add a fake part that is not |
|
// included in the message itself |
|
KMMessagePart *fake = new KMMessagePart(); |
|
QString partId = part->partSpecifier().section( '.', 0, -2 ) + ".HEADER"; |
|
fake->setPartSpecifier( partId ); |
|
fake->setOriginalContentTypeStr(""); |
|
fake->setLoadPart( true ); |
|
if ( addPartToList( fake ) ) { |
|
selected.append( fake ); |
|
} |
|
} |
|
|
|
if ( part->originalContentTypeStr() == "MESSAGE/RFC822" ) { |
|
headerCheck = true; |
|
} else { |
|
headerCheck = false; |
|
} |
|
|
|
// check whether to load this part or not: |
|
// look at the basic list, ask the subclass and check the parent |
|
if ( mBasicList.contains( part->originalContentTypeStr() ) || |
|
parentNeedsLoading( part ) || |
|
addPartToList( part ) ) { |
|
if ( part->typeStr() != "MULTIPART" || |
|
part->partSpecifier().endsWith(".HEADER") ) { |
|
// load the part itself |
|
part->setLoadPart( true ); |
|
} |
|
} |
|
if ( !part->partSpecifier().endsWith(".HEADER") && |
|
part->typeStr() != "MULTIPART" ) { |
|
part->setLoadHeaders( true ); // load MIME header |
|
} |
|
|
|
if ( part->loadHeaders() || part->loadPart() ) { |
|
selected.append( part ); |
|
} |
|
} |
|
return selected; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool BodyVisitor::parentNeedsLoading( KMMessagePart *msgPart ) |
|
{ |
|
KMMessagePart *part = msgPart; |
|
while ( part ) { |
|
if ( part->parent() && |
|
( part->parent()->originalContentTypeStr() == "MULTIPART/SIGNED" || |
|
( msgPart->originalContentTypeStr() == "APPLICATION/OCTET-STREAM" && |
|
part->parent()->originalContentTypeStr() == "MULTIPART/ENCRYPTED" ) ) ) { |
|
return true; |
|
} |
|
|
|
part = part->parent(); |
|
} |
|
return false; |
|
} |
|
|
|
//============================================================================= |
|
|
|
BodyVisitorSmart::BodyVisitorSmart() : BodyVisitor() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool BodyVisitorSmart::addPartToList( KMMessagePart *part ) |
|
{ |
|
// header of an encapsulated message |
|
if ( part->partSpecifier().endsWith(".HEADER") ) { |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//============================================================================= |
|
|
|
BodyVisitorInline::BodyVisitorInline() : BodyVisitor() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool BodyVisitorInline::addPartToList( KMMessagePart *part ) |
|
{ |
|
if ( part->partSpecifier().endsWith(".HEADER") ) { |
|
// header of an encapsulated message |
|
return true; |
|
} else if ( part->typeStr() == "IMAGE" ) { |
|
// images |
|
return true; |
|
} else if ( part->typeStr() == "TEXT" ) { |
|
// text, diff and stuff |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//============================================================================= |
|
|
|
BodyVisitorHidden::BodyVisitorHidden() : BodyVisitor() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool BodyVisitorHidden::addPartToList( KMMessagePart *part ) |
|
{ |
|
// header of an encapsulated message |
|
if ( part->partSpecifier().endsWith(".HEADER") ) { |
|
return true; |
|
} |
|
|
|
return false; |
|
}
|
|
|