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

453 lines
10 KiB
C++

/*
KNode, the KDE newsreader
Copyright (c) 1999-2005 the KNode authors.
See file AUTHORS for details
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.
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, US
*/
#include "knarticle.h"
#include "knhdrviewitem.h"
#include "kngroup.h"
#include "knglobals.h"
#include "knconfigmanager.h"
#include "settings.h"
#include "utilities.h"
#include "utils/locale.h"
#include <kcodecs.h>
#include <kmimetype.h>
using namespace KNode::Utilities;
using namespace KMime;
KNArticle::KNArticle( KNArticleCollection::Ptr c )
: i_d( -1 ), c_ol( c ), i_tem( 0 )
{
}
KNArticle::~KNArticle()
{
delete i_tem;
}
void KNArticle::clear()
{
f_lags.clear();
}
void KNArticle::setListItem( KNHdrViewItem *it, KNArticle::Ptr a )
{
Q_ASSERT_X( this == a.get(), "KNArticle::setListItem", "By contract, setListItem second parameter must be a reference to 'this' article" );
i_tem=it;
if( i_tem ) {
i_tem->art = a;
}
}
void KNArticle::setLocked(bool b)
{
f_lags.set(0, b);
if(c_ol) { // local articles may have c_ol==0 !
if(b)
c_ol->articleLocked();
else
c_ol->articleUnlocked();
}
}
//=========================================================================================
KNRemoteArticle::KNRemoteArticle( KNGroup::Ptr g )
: KNArticle(g), a_rticleNumber(-1), i_dRef(-1), t_hrLevel(0), s_core(0),
c_olor(knGlobals.settings()->unreadThreadColor()),
u_nreadFups(0), n_ewFups(0), s_ubThreadChangeDate(0)
{
setDefaultCharset( Locale::defaultCharset( g ) );
// Remote article are read-only
setFrozen( true );
}
KNRemoteArticle::~KNRemoteArticle()
{}
void KNRemoteArticle::parse()
{
KNArticle::parse();
QByteArray raw;
raw = KMime::extractHeader( head(), from()->type() );
if ( !raw.isEmpty() ) {
QByteArray f;
Locale::encodeTo7Bit( raw, defaultCharset(), f );
from()->from7BitString( f );
}
raw = KMime::extractHeader( head(), subject()->type() );
if( !raw.isEmpty() ) {
QByteArray subjectStr;
Locale::encodeTo7Bit( raw, defaultCharset(), subjectStr );
subject()->from7BitString( subjectStr );
}
}
void KNRemoteArticle::initListItem()
{
if(!i_tem) return;
KMime::Types::Mailbox mbox;
if ( !from()->isEmpty() ) {
mbox = from()->mailboxes().first();
}
if ( mbox.hasName() )
i_tem->setText( 1, mbox.name() );
else
i_tem->setText( 1, QString::fromLatin1( mbox.address() ) );
updateListItem();
}
void KNRemoteArticle::updateListItem()
{
if(!i_tem) return;
KNode::Appearance *app=knGlobals.configManager()->appearance();
if(isRead()) {
if(hasContent())
i_tem->setPixmap(0, app->icon(KNode::Appearance::greyBallChkd));
else
i_tem->setPixmap(0, app->icon(KNode::Appearance::greyBall));
}
else {
if(hasContent())
i_tem->setPixmap(0,app->icon(KNode::Appearance::redBallChkd));
else
i_tem->setPixmap(0, app->icon(KNode::Appearance::redBall));
}
if(hasNewFollowUps())
i_tem->setPixmap(1, app->icon(KNode::Appearance::newFups));
else
i_tem->setPixmap(1, app->icon(KNode::Appearance::null));
if(isWatched())
i_tem->setPixmap(2, app->icon(KNode::Appearance::eyes));
else {
if(isIgnored())
i_tem->setPixmap(2, app->icon(KNode::Appearance::ignore));
else
i_tem->setPixmap(2, app->icon(KNode::Appearance::null));
}
i_tem->setExpandable( (threadMode() && hasVisibleFollowUps()) );
i_tem->repaint(); //force repaint
}
void KNRemoteArticle::thread(KNRemoteArticle::List &l)
{
KNRemoteArticle::Ptr tmp;
KNGroup::Ptr g = boost::static_pointer_cast<KNGroup>( c_ol );
int idRef=i_dRef, topID=-1;
KNRemoteArticle::Ptr ref = g->byId( id() ); // get self reference
while(idRef!=0) {
ref=g->byId(idRef);
if(!ref)
return; // sh#t !!
idRef=ref->idRef();
}
topID=ref->id();
l.append(ref);
for(int i=0; i<g->length(); ++i) {
tmp=g->at(i);
if(tmp->idRef()!=0) {
idRef=tmp->idRef();
while(idRef!=0) {
ref=g->byId(idRef);
idRef=ref->idRef();
}
if(ref->id()==topID)
l.append(tmp);
}
}
}
void KNRemoteArticle::setForceDefaultCharset(bool b)
{
if (!b) { // restore default
KNGroup::Ptr g = boost::static_pointer_cast<KNGroup>( c_ol );
setDefaultCharset( Locale::defaultCharset( g ) );
}
KNArticle::setForceDefaultCharset( b );
initListItem();
}
void KNRemoteArticle::propagateThreadChangedDate()
{
KNGroup::Ptr g = boost::static_pointer_cast<KNGroup>( c_ol );
KNRemoteArticle::Ptr ref = g->byId( id() );
int idRef=i_dRef;
while (idRef!=0) {
ref=g->byId(idRef);
if(!ref)
return; // sh#t !!
idRef=ref->idRef();
}
if (date()->dateTime() > ref->date()->dateTime()) {
ref->setSubThreadChangeDate(date()->dateTime().toTime_t());
}
}
//=========================================================================================
KNLocalArticle::KNLocalArticle( KNArticleCollection::Ptr c )
: KNArticle(c), s_Offset(0), e_Offset(0), s_erverId(-1)
{
setDefaultCharset( Locale::defaultCharset() );
}
KNLocalArticle::~KNLocalArticle()
{}
void KNLocalArticle::updateListItem()
{
if(!i_tem)
return;
QString tmp;
int idx=0;
KNode::Appearance *app=knGlobals.configManager()->appearance();
if(isSavedRemoteArticle()) {
i_tem->setPixmap(0, app->icon(KNode::Appearance::savedRemote));
Headers::Newsgroups *hdrNewsgroup = newsgroups( false );
if ( hdrNewsgroup && !hdrNewsgroup->isEmpty() ) {
tmp = hdrNewsgroup->asUnicodeString();
} else {
Headers::To *hdrTo = to( false );
if ( hdrTo && !hdrTo->isEmpty() ) {
tmp = hdrTo->asUnicodeString();
}
}
} else {
if(doPost()) {
tmp += newsgroups()->asUnicodeString();
if(canceled())
i_tem->setPixmap(idx++, app->icon(KNode::Appearance::canceledPosting));
else
i_tem->setPixmap(idx++, app->icon(KNode::Appearance::posting));
}
if(doMail()) {
i_tem->setPixmap(idx++, app->icon(KNode::Appearance::mail));
if(doPost())
tmp+=" / ";
tmp += to()->asUnicodeString();
}
}
i_tem->setText(1, tmp);
}
void KNLocalArticle::setForceDefaultCharset( bool b )
{
if (!b) // restore default
setDefaultCharset( Locale::defaultCharset() );
KNArticle::setForceDefaultCharset( b );
updateListItem();
}
//=========================================================================================
KNAttachment::KNAttachment(Content *c)
: c_ontent(c), l_oadHelper(0), f_ile(0), i_sAttached(true)
{
Headers::ContentType *t=c->contentType();
Headers::ContentTransferEncoding *e=c->contentTransferEncoding();
Headers::ContentDescription *d=c->contentDescription(false);
n_ame=t->name();
if(d)
d_escription=d->asUnicodeString();
setMimeType(t->mimeType());
if(e->encoding()==Headers::CEuuenc) {
setCte( Headers::CEbase64 );
updateContentInfo();
}
else
e_ncoding.setEncoding( e->encoding() );
h_asChanged=false; // has been set to "true" in setMimeType()
}
KNAttachment::KNAttachment(KNLoadHelper *helper)
: c_ontent(0), l_oadHelper(helper), f_ile(helper->getFile()), i_sAttached(false), h_asChanged(true)
{
setMimeType(KMimeType::findByPath(f_ile->fileName())->name());
n_ame=helper->getURL().fileName();
}
KNAttachment::~KNAttachment()
{
if(!i_sAttached && c_ontent)
delete c_ontent;
delete l_oadHelper;
}
void KNAttachment::setMimeType(const QString &s)
{
mMimeType = s;
h_asChanged=true;
if ( !mMimeType.contains( "text/", Qt::CaseInsensitive ) ) {
f_b64=true;
e_ncoding.setEncoding(Headers::CEbase64);
}
else {
f_b64=false;
if ( knGlobals.settings()->allow8BitBody() )
setCte(Headers::CE8Bit);
else
setCte(Headers::CEquPr);
}
}
QString KNAttachment::contentSize() const
{
int s=0;
if(c_ontent && c_ontent->hasContent())
s=c_ontent->size();
else {
if (f_ile)
s=f_ile->size();
}
return KGlobal::locale()->formatByteSize( s );
}
void KNAttachment::updateContentInfo()
{
if(!h_asChanged || !c_ontent)
return;
//Content-Type
Headers::ContentType *t=c_ontent->contentType();
t->setMimeType( mMimeType.toLatin1() );
t->setName(n_ame, "UTF-8");
t->setCategory(Headers::CCmixedPart);
//Content-Description
if(d_escription.isEmpty())
c_ontent->removeHeader("Content-Description");
else
c_ontent->contentDescription()->fromUnicodeString(d_escription, "UTF-8");
//Content-Disposition
Headers::ContentDisposition *d=c_ontent->contentDisposition();
d->setDisposition(Headers::CDattachment);
d->setFilename(n_ame);
//Content-Transfer-Encoding
if(i_sAttached)
c_ontent->changeEncoding(e_ncoding.encoding());
else
c_ontent->contentTransferEncoding()->setEncoding(e_ncoding.encoding());
c_ontent->assemble();
h_asChanged=false;
}
void KNAttachment::attach(Content *c)
{
if(i_sAttached || !f_ile)
return;
c_ontent=new Content();
updateContentInfo();
Headers::ContentType *type=c_ontent->contentType();
Headers::ContentTransferEncoding *e=c_ontent->contentTransferEncoding();
QByteArray data;
data = f_ile->readAll();
if ( data.size() < f_ile->size() && f_ile->error() != QFile::NoError ) {
KNHelper::displayExternalFileError();
delete c_ontent;
c_ontent=0;
} else {
if (e_ncoding.encoding()==Headers::CEbase64 || !type->isText()) { //encode base64
c_ontent->setBody( KCodecs::base64Encode(data, true) + '\n' );
// c_ontent->b_ody += '\n';
e->setEncoding(Headers::CEbase64);
e->setDecoded(false);
} else {
c_ontent->setBody( data + '\n' );
// c_ontent->b_ody += '\n';
e->setDecoded(true);
}
}
if(c_ontent) {
c->addContent(c_ontent);
i_sAttached=true;
}
}
void KNAttachment::detach(Content *c)
{
if(i_sAttached) {
c->removeContent(c_ontent, false);
i_sAttached=false;
}
}