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.
tdepim/knode/knarticlefactory.cpp

1112 lines
32 KiB

/*
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 <tqlayout.h>
#include <tqlabel.h>
#include <tqvbox.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kwin.h>
#include <kapplication.h>
#include "knarticlefactory.h"
#include "knglobals.h"
#include "knconfigmanager.h"
#include "kngroupmanager.h"
#include "knaccountmanager.h"
#include "knfoldermanager.h"
#include "knarticlemanager.h"
#include "knfolder.h"
#include "kncomposer.h"
#include "knnntpaccount.h"
#include "utilities.h"
#include "resource.h"
KNArticleFactory::KNArticleFactory(TQObject *p, const char *n)
: TQObject(p, n), s_endErrDlg(0)
{
}
KNArticleFactory::~KNArticleFactory()
{
for ( TQValueList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
delete (*it);
delete s_endErrDlg;
}
void KNArticleFactory::createPosting(KNNntpAccount *a)
{
if(!a)
return;
TQString sig;
KNLocalArticle *art=newArticle(a, sig, knGlobals.configManager()->postNewsTechnical()->charset());
if(!art)
return;
art->setServerId(a->id());
art->setDoPost(true);
art->setDoMail(false);
KNComposer *c = new KNComposer( art, TQString(), sig, TQString(), true );
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::createPosting(KNGroup *g)
{
if(!g)
return;
TQCString chset;
if (g->useCharset())
chset = g->defaultCharset();
else
chset = knGlobals.configManager()->postNewsTechnical()->charset();
TQString sig;
KNLocalArticle *art=newArticle(g, sig, chset);
if(!art)
return;
art->setServerId(g->account()->id());
art->setDoPost(true);
art->setDoMail(false);
art->newsgroups()->fromUnicodeString(g->groupname(), art->defaultCharset());
KNComposer *c=new KNComposer(art, TQString(), sig, TQString(), true);
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::createReply(KNRemoteArticle *a, TQString selectedText, bool post, bool mail)
{
if(!a)
return;
KNGroup *g=static_cast<KNGroup*>(a->collection());
TQCString chset;
if (knGlobals.configManager()->postNewsTechnical()->useOwnCharset()) {
if (g->useCharset())
chset = g->defaultCharset();
else
chset = knGlobals.configManager()->postNewsTechnical()->charset();
} else
chset = knGlobals.configManager()->postNewsTechnical()->findComposerCharset(a->contentType()->charset());
//create new article
TQString sig;
KNLocalArticle *art=newArticle(g, sig, chset, true, a);
if(!art)
return;
art->setServerId(g->account()->id());
art->setDoPost(post);
art->setDoMail(mail);
//------------------------- <Headers> ----------------------------
//subject
TQString subject=a->subject()->asUnicodeString();
if(subject.left(3).upper()!="RE:")
subject.prepend("Re: ");
art->subject()->fromUnicodeString(subject, a->subject()->rfc2047Charset());
//newsgroups
KMime::Headers::FollowUpTo *fup2=a->followUpTo(false);
if(fup2 && !fup2->isEmpty()) {
if( ( fup2->as7BitString(false).upper()=="POSTER" ) ) { //Followup-To: poster
if( post && // user wanted to reply by public posting?
// ask the user if she wants to ignore this F'up-To: poster
( KMessageBox::Yes != KMessageBox::questionYesNo(knGlobals.topWidget,
i18n("The author has requested a reply by email instead\nof a followup to the newsgroup. (Followup-To: poster)\nDo you want to reply in public anyway?"), TQString(), i18n("Reply Public"), i18n("Reply by Email")) ))
{
art->setDoPost(false);
art->setDoMail(true);
}
art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
}
else
art->newsgroups()->from7BitString(fup2->as7BitString(false));
}
else
art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
//To
KMime::Headers::ReplyTo *replyTo=a->replyTo(false);
KMime::Headers::AddressField address;
if(replyTo && !replyTo->isEmpty()) {
if(replyTo->hasName())
address.setName(replyTo->name());
if(replyTo->hasEmail())
address.setEmail(replyTo->email().copy());
}
else {
KMime::Headers::From *from=a->from();
if(from->hasName())
address.setName(from->name());
if(from->hasEmail())
address.setEmail(from->email().copy());
}
art->to()->addAddress(address);
//References
KMime::Headers::References *references=a->references(false);
TQCString refs;
if (references)
refs=references->as7BitString(false);
else
refs = "";
art->references()->from7BitString(refs);
art->references()->append(a->messageID()->as7BitString(false));
//Mail-Copies-To
bool authorDislikesMailCopies=false;
bool authorWantsMailCopies=false;
KMime::Headers::MailCopiesTo *mailCopiesTo=a->mailCopiesTo(false);
if(mailCopiesTo && !mailCopiesTo->isEmpty() && mailCopiesTo->isValid()) {
authorDislikesMailCopies = mailCopiesTo->neverCopy();
authorWantsMailCopies = mailCopiesTo->alwaysCopy();
if (authorWantsMailCopies) // warn the user
KMessageBox::information(knGlobals.topWidget,i18n("The author requested a mail copy of your reply. (Mail-Copies-To header)"),
TQString(),"mailCopiesToWarning");
if (authorWantsMailCopies && mailCopiesTo->hasEmail()) {
address.setName(mailCopiesTo->name());
address.setEmail(mailCopiesTo->email());
art->to()->clear();
art->to()->addAddress(address);
}
}
//------------------------- </Headers> ---------------------------
//--------------------------- <Body> -----------------------------
// attribution line
TQString attribution=knGlobals.configManager()->postNewsComposer()->intro();
TQString name(a->from()->name());
if (name.isEmpty())
name = TQString::tqfromLatin1(a->from()->email());
attribution.tqreplace(TQRegExp("%NAME"),name);
attribution.tqreplace(TQRegExp("%EMAIL"),TQString::tqfromLatin1(a->from()->email()));
attribution.tqreplace(TQRegExp("%DATE"),KGlobal::locale()->formatDateTime(a->date()->qdt(),false));
attribution.tqreplace(TQRegExp("%MSID"),a->messageID()->asUnicodeString());
attribution.tqreplace(TQRegExp("%GROUP"),g->groupname());
attribution.tqreplace(TQRegExp("%L"),"\n");
attribution+="\n\n";
TQString quoted=attribution;
TQString notRewraped=TQString();
TQStringList text;
TQStringList::Iterator line;
bool incSig=knGlobals.configManager()->postNewsComposer()->includeSignature();
if (selectedText.isEmpty()) {
KMime::Content *tc = a->textContent();
if(tc)
tc->decodedText(text, true, knGlobals.configManager()->readNewsViewer()->removeTrailingNewlines());
}
else
text = TQStringList::split('\n',selectedText,true);
for(line=text.begin(); line!=text.end(); ++line) {
if(!incSig && (*line)=="-- ")
break;
if ((*line)[0]=='>')
quoted+=">"+(*line)+"\n"; // second quote level without space
else
quoted+="> "+(*line)+"\n";
}
if(knGlobals.configManager()->postNewsComposer()->rewrap()) { //rewrap original article
notRewraped=quoted; // store the original text in here, the user can request it in the composer
quoted=attribution;
quoted += KNHelper::rewrapStringList(text, knGlobals.configManager()->postNewsComposer()->maxLineLength(), '>', !incSig, false);
}
//-------------------------- </Body> -----------------------------
if (art->doMail() && knGlobals.configManager()->postNewsTechnical()->useExternalMailer()) {
sendMailExternal(address.asUnicodeString(), subject, quoted);
art->setDoMail(false);
if (!art->doPost()) {
delete art;
return;
}
}
//open composer
KNComposer *c=new KNComposer(art, quoted, sig, notRewraped, true, authorDislikesMailCopies, authorWantsMailCopies);
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::createForward(KNArticle *a)
{
if(!a)
return;
KMime::Headers::ContentType *ct=a->contentType();
TQCString chset;
bool incAtt = ( !knGlobals.configManager()->postNewsTechnical()->useExternalMailer() &&
ct->isMultipart() && ct->isSubtype("mixed") &&
KMessageBox::Yes == KMessageBox::questionYesNo(knGlobals.topWidget,
i18n("This article contains attachments. Do you want them to be forwarded as well?"), TQString(), i18n("Forward"), i18n("Do Not Forward"))
);
if (knGlobals.configManager()->postNewsTechnical()->useOwnCharset())
chset = knGlobals.configManager()->postNewsTechnical()->charset();
else
chset = knGlobals.configManager()->postNewsTechnical()->findComposerCharset(a->contentType()->charset());
//create new article
TQString sig;
KNLocalArticle *art=newArticle(knGlobals.groupManager()->currentGroup(), sig, chset);
if(!art)
return;
art->setDoPost(false);
art->setDoMail(true);
//------------------------- <Headers> ----------------------------
//subject
TQString subject=("Fwd: "+a->subject()->asUnicodeString());
art->subject()->fromUnicodeString(subject, a->subject()->rfc2047Charset());
//------------------------- </Headers> ---------------------------
//--------------------------- <Body> -----------------------------
TQString fwd = TQString("\n--------------- %1\n\n").arg(i18n("Forwarded message (begin)"));
fwd+=( i18n("Subject") + ": " + a->subject()->asUnicodeString() + "\n" );
fwd+=( i18n("From") + ": " + a->from()->asUnicodeString() + "\n" );
fwd+=( i18n("Date") + ": " + a->date()->asUnicodeString() + "\n" );
fwd+=( i18n("Newsgroup") + ": " + a->newsgroups()->asUnicodeString() + "\n\n" );
KMime::Content *text=a->textContent();
if(text) {
TQStringList decodedLines;
text->decodedText( decodedLines, false, false );
for(TQStringList::Iterator it=decodedLines.begin(); it!=decodedLines.end(); ++it)
fwd += (*it) + "\n";
}
fwd += TQString("\n--------------- %1\n").arg(i18n("Forwarded message (end)"));
//--------------------------- </Body> ----------------------------
//------------------------ <Attachments> -------------------------
if(incAtt) {
KMime::Content::List al;
a->attachments(&al, false);
for(KMime::Content *c=al.first(); c; c=al.next()) {
art->addContent( new KMime::Content(c->head(), c->body()) );
}
}
//------------------------ </Attachments> ------------------------
if (knGlobals.configManager()->postNewsTechnical()->useExternalMailer()) {
sendMailExternal(TQString(), subject, fwd);
delete art;
return;
}
//open composer
KNComposer *c=new KNComposer(art, fwd, sig, TQString(), true);
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::createCancel(KNArticle *a)
{
if(!cancelAllowed(a))
return;
if(KMessageBox::No==KMessageBox::questionYesNo(knGlobals.topWidget,
i18n("Do you really want to cancel this article?"), TQString(), i18n("Cancel Article"), KStdGuiItem::cancel()))
return;
bool sendNow;
switch (KMessageBox::warningYesNoCancel(knGlobals.topWidget, i18n("Do you want to send the cancel\nmessage now or later?"), i18n("Question"),i18n("&Now"),i18n("&Later"))) {
case KMessageBox::Yes : sendNow = true; break;
case KMessageBox::No : sendNow = false; break;
default : return;
}
KNGroup *grp;
KNNntpAccount *nntp=0;
if(a->type()==KMime::Base::ATremote)
nntp=(static_cast<KNGroup*>(a->collection()))->account();
else {
if(!nntp)
nntp=knGlobals.accountManager()->first();
if(!nntp) {
KMessageBox::error(knGlobals.topWidget, i18n("You have no valid news accounts configured."));
return;
}
KNLocalArticle *la=static_cast<KNLocalArticle*>(a);
la->setCanceled(true);
la->updateListItem();
nntp=knGlobals.accountManager()->account(la->serverId());
}
grp=knGlobals.groupManager()->group(a->newsgroups()->firstGroup(), nntp);
TQString sig;
KNLocalArticle *art=newArticle(grp, sig, "us-ascii", false);
if(!art)
return;
//init
art->setDoPost(true);
art->setDoMail(false);
//server
art->setServerId(nntp->id());
//subject
KMime::Headers::MessageID *msgId=a->messageID();
TQCString tmp;
tmp="cancel of "+msgId->as7BitString(false);
art->subject()->from7BitString(tmp);
//newsgroups
art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
//control
tmp="cancel "+msgId->as7BitString(false);
art->control()->from7BitString(tmp);
//Lines
art->lines()->setNumberOfLines(1);
//body
art->fromUnicodeString(TQString::tqfromLatin1("cancel by original author\n"));
//assemble
art->assemble();
//send
KNLocalArticle::List lst;
lst.append(art);
sendArticles( lst, sendNow );
}
void KNArticleFactory::createSupersede(KNArticle *a)
{
if (!a)
return;
if(!cancelAllowed(a))
return;
if(KMessageBox::No==KMessageBox::questionYesNo(knGlobals.topWidget,
i18n("Do you really want to supersede this article?"), TQString(), i18n("Supersede"), KStdGuiItem::cancel()))
return;
KNGroup *grp;
KNNntpAccount *nntp;
if(a->type()==KMime::Base::ATremote)
nntp=(static_cast<KNGroup*>(a->collection()))->account();
else {
KNLocalArticle *la=static_cast<KNLocalArticle*>(a);
la->setCanceled(true);
la->updateListItem();
nntp=knGlobals.accountManager()->account(la->serverId());
if(!nntp)
nntp=knGlobals.accountManager()->first();
if(!nntp) {
KMessageBox::error(knGlobals.topWidget, i18n("You have no valid news accounts configured."));
return;
}
}
grp=knGlobals.groupManager()->group(a->newsgroups()->firstGroup(), nntp);
//new article
TQString sig;
KNLocalArticle *art=newArticle(grp, sig, knGlobals.configManager()->postNewsTechnical()->findComposerCharset(a->contentType()->charset()));
if(!art)
return;
art->setDoPost(true);
art->setDoMail(false);
//server
art->setServerId(nntp->id());
//subject
art->subject()->fromUnicodeString(a->subject()->asUnicodeString(), a->subject()->rfc2047Charset());
//newsgroups
art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
//followup-to
art->followUpTo()->from7BitString(a->followUpTo()->as7BitString(false));
//References
if ( !a->references()->isEmpty() )
art->references()->from7BitString( a->references()->as7BitString(false) );
//Supersedes
art->supersedes()->from7BitString(a->messageID()->as7BitString(false));
//Body
TQString text;
KMime::Content *textContent=a->textContent();
if(textContent)
textContent->decodedText(text);
//open composer
KNComposer *c=new KNComposer(art, text, sig);
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::createMail(KMime::Headers::AddressField *address)
{
if (knGlobals.configManager()->postNewsTechnical()->useExternalMailer()) {
sendMailExternal(address->asUnicodeString());
return;
}
//create new article
TQString sig;
KNLocalArticle *art=newArticle(knGlobals.groupManager()->currentGroup(), sig, knGlobals.configManager()->postNewsTechnical()->charset());
if(!art)
return;
art->setDoMail(true);
art->setDoPost(false);
art->to()->addAddress((*address));
//open composer
KNComposer *c=new KNComposer(art, TQString(), sig, TQString(), true);
mCompList.append( c );
connect(c, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
c->show();
}
void KNArticleFactory::sendMailExternal(const TQString &address, const TQString &subject, const TQString &body)
{
KURL mailtoURL;
TQStringList queries;
TQString query=TQString();
mailtoURL.setProtocol("mailto");
if (!address.isEmpty())
mailtoURL.setPath(address);
if (!subject.isEmpty())
queries.append("subject="+KURL::encode_string(subject));
if (!body.isEmpty())
queries.append("body="+KURL::encode_string(body));
if (queries.count() > 0) {
query = "?";
for ( TQStringList::Iterator it = queries.begin(); it != queries.end(); ++it ) {
if (it != queries.begin())
query.append("&");
query.append((*it));
}
}
if (!query.isEmpty())
mailtoURL.setQuery(query);
kapp->invokeMailer(mailtoURL);
}
void KNArticleFactory::edit(KNLocalArticle *a)
{
if(!a)
return;
KNComposer *com=findComposer(a);
if(com) {
KWin::activateWindow(com->winId());
return;
}
if(a->editDisabled()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("This article cannot be edited."));
return;
}
//find signature
KNConfig::Identity *id=knGlobals.configManager()->identity();
if(a->doPost()) {
KNNntpAccount *acc=knGlobals.accountManager()->account(a->serverId());
if(acc) {
KMime::Headers::Newsgroups *grps=a->newsgroups();
KNGroup *grp=knGlobals.groupManager()->group(grps->firstGroup(), acc);
if (grp && grp->identity())
id=grp->identity();
else if (acc->identity())
id=acc->identity();
}
}
//load article body
if(!a->hasContent())
knGlobals.articleManager()->loadArticle(a);
//open composer
com=new KNComposer(a, TQString(), id->getSignature());
if(id->useSigGenerator() && !id->getSigGeneratorStdErr().isEmpty())
KMessageBox::information(knGlobals.topWidget,
i18n("<qt>The signature generator program produced the "
"following output:<br><br>%1</qt>")
.arg(id->getSigGeneratorStdErr()));
mCompList.append( com );
connect(com, TQT_SIGNAL(composerDone(KNComposer*)), this, TQT_SLOT(slotComposerDone(KNComposer*)));
com->show();
}
void KNArticleFactory::sendArticles( KNLocalArticle::List &l, bool now )
{
KNJobData *job=0;
KNServerInfo *ser=0;
KNLocalArticle::List unsent, sent;
for ( KNLocalArticle::List::Iterator it = l.begin(); it != l.end(); ++it ) {
if ( (*it)->pending() )
unsent.append( (*it) );
else
sent.append( (*it) );
}
if(!sent.isEmpty()) {
showSendErrorDialog();
for ( KNLocalArticle::List::Iterator it = sent.begin(); it != sent.end(); ++it )
s_endErrDlg->append( (*it)->subject()->asUnicodeString(), i18n("Article has already been sent.") );
}
if(!now) {
knGlobals.articleManager()->moveIntoFolder(unsent, knGlobals.folderManager()->outbox());
return;
}
for ( KNLocalArticle::List::Iterator it = unsent.begin(); it != unsent.end(); ++it ) {
if ( (*it)->isLocked() )
continue;
if ( !(*it)->hasContent() ) {
if ( !knGlobals.articleManager()->loadArticle( (*it) ) ) {
showSendErrorDialog();
s_endErrDlg->append( (*it)->subject()->asUnicodeString(), i18n("Unable to load article.") );
continue;
}
}
if ( (*it)->doPost() && !(*it)->posted() ) {
ser = knGlobals.accountManager()->account( (*it)->serverId() );
job = new KNJobData( KNJobData::JTpostArticle, this, ser, (*it) );
emitJob(job);
}
else if( (*it)->doMail() && !(*it)->mailed() ) {
ser = knGlobals.accountManager()->smtp();
job = new KNJobData( KNJobData::JTmail, this, ser, (*it) );
emitJob(job);
}
}
}
void KNArticleFactory::sendOutbox()
{
KNLocalArticle::List lst;
KNFolder *ob=0;
if(!knGlobals.folderManager()->loadOutbox()) {
KMessageBox::error(knGlobals.topWidget, i18n("Unable to load the outbox-folder."));
return;
}
ob=knGlobals.folderManager()->outbox();
for(int i=0; i< ob->length(); i++)
lst.append(ob->at(i));
sendArticles( lst, true );
}
bool KNArticleFactory::closeComposeWindows()
{
while ( !mCompList.isEmpty() ) {
TQValueList<KNComposer*>::Iterator it = mCompList.begin();
if ( !(*it)->close() )
return false;
}
return true;
}
void KNArticleFactory::deleteComposerForArticle(KNLocalArticle *a)
{
KNComposer *com = findComposer( a );
if ( com ) {
mCompList.remove( com );
delete com;
}
}
KNComposer* KNArticleFactory::findComposer(KNLocalArticle *a)
{
for ( TQValueList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
if ( (*it)->article() == a )
return (*it);
return 0;
}
void KNArticleFactory::configChanged()
{
for ( TQValueList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
(*it)->setConfig( false );
}
void KNArticleFactory::processJob(KNJobData *j)
{
KNLocalArticle *art=static_cast<KNLocalArticle*>(j->data());
KNLocalArticle::List lst;
lst.append(art);
if(j->canceled()) {
delete j;
//sending of this article was canceled => move it to the "Outbox-Folder"
if(art->collection()!=knGlobals.folderManager()->outbox())
knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->outbox());
KMessageBox::information(knGlobals.topWidget, i18n("You have aborted the posting of articles. The unsent articles are stored in the \"Outbox\" folder."));
return;
}
if(!j->success()) {
showSendErrorDialog();
s_endErrDlg->append(art->subject()->asUnicodeString(), j->errorString());
delete j; //unlock article
//sending of this article failed => move it to the "Outbox-Folder"
if(art->collection()!=knGlobals.folderManager()->outbox())
knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->outbox());
}
else {
//disable edit
art->setEditDisabled(true);
switch(j->type()) {
case KNJobData::JTpostArticle:
delete j; //unlock article
art->setPosted(true);
if(art->doMail() && !art->mailed()) { //article has been posted, now mail it
sendArticles( lst, true );
return;
}
break;
case KNJobData::JTmail:
delete j; //unlock article
art->setMailed(true);
break;
default: break;
};
//article has been sent successfully => move it to the "Sent-folder"
knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->sent());
}
}
KNLocalArticle* KNArticleFactory::newArticle(KNCollection *col, TQString &sig, TQCString defChset, bool withXHeaders, KNArticle *origPost)
{
KNConfig::PostNewsTechnical *pnt=knGlobals.configManager()->postNewsTechnical();
if(pnt->generateMessageID() && pnt->hostname().isEmpty()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("Please set a hostname for the generation\nof the message-id or disable it."));
return 0;
}
KNLocalArticle *art=new KNLocalArticle(0);
KNConfig::Identity *tmpId=0, *id=0;
if (col) {
if (col->type() == KNCollection::CTgroup) {
id = (static_cast<KNGroup *>(col))->identity();
tmpId = (static_cast<KNGroup *>(col))->account()->identity();
} else
if (col->type() == KNCollection::CTnntpAccount) {
id = (static_cast<KNNntpAccount *>(col))->identity();
}
}
// determine active innermost non-empty identity
if (!id) {
if (tmpId)
id = tmpId;
else
id = knGlobals.configManager()->identity();
}
//Message-id
if(pnt->generateMessageID())
art->messageID()->generate(pnt->hostname());
//From
KMime::Headers::From *from=art->from();
from->setRFC2047Charset(pnt->charset());
//name
if(id->hasName())
from->setName(id->name());
//email
if(id->hasEmail()&&id->emailIsValid())
from->setEmail(id->email().latin1());
else {
if ( id->hasEmail() )
KMessageBox::sorry(knGlobals.topWidget,
i18n("Please enter a valid email address at the identity tab of the account configuration dialog."));
else
KMessageBox::sorry(knGlobals.topWidget,
i18n("Please enter a valid email address at the identity section of the configuration dialog."));
delete art;
return 0;
}
//Reply-To
if(id->hasReplyTo()) {
art->replyTo()->fromUnicodeString(id->replyTo(), pnt->charset());
if (!art->replyTo()->hasEmail()) // the header is invalid => drop it
art->removeHeader("Reply-To");
}
//Mail-Copies-To
if(id->hasMailCopiesTo()) {
art->mailCopiesTo()->fromUnicodeString(id->mailCopiesTo(), pnt->charset());
if (!art->mailCopiesTo()->isValid()) // the header is invalid => drop it
art->removeHeader("Mail-Copies-To");
}
//Organization
if(id->hasOrga())
art->organization()->fromUnicodeString(id->orga(), pnt->charset());
//Date
art->date()->setUnixTime(); //set current date+time
//User-Agent
if( !pnt->noUserAgent() ) {
art->userAgent()->from7BitString("KNode/" KNODE_VERSION);
}
//Mime
KMime::Headers::ContentType *type=art->contentType();
type->setMimeType("text/plain");
type->setCharset(defChset);
if (defChset.lower()=="us-ascii")
art->contentTransferEncoding()->setCte(KMime::Headers::CE7Bit);
else
art->contentTransferEncoding()->setCte(pnt->allow8BitBody()? KMime::Headers::CE8Bit : KMime::Headers::CEquPr);
//X-Headers
if(withXHeaders) {
KNConfig::XHeaders::Iterator it;
for(it=pnt->xHeaders().begin(); it!=pnt->xHeaders().end(); ++it) {
TQString value = (*it).value();
if(origPost) {
TQString name(origPost->from()->name());
if (name.isEmpty())
name = TQString::tqfromLatin1(origPost->from()->email());
value.tqreplace(TQRegExp("%NAME"), name);
value.tqreplace(TQRegExp("%EMAIL"), TQString::tqfromLatin1(origPost->from()->email()));
}
else
if(value.tqfind("%NAME") != -1 || value.tqfind("%EMAIL") != -1)
continue;
art->setHeader( new KMime::Headers::Generic( (TQCString("X-")+(*it).name()), art, value, pnt->charset() ) );
}
}
//Signature
if(id->hasSignature())
{
sig=id->getSignature();
if(id->useSigGenerator() && !id->getSigGeneratorStdErr().isEmpty())
KMessageBox::information(knGlobals.topWidget,
i18n("<qt>The signature generator program produced the "
"following output:<br><br>%1</qt>")
.arg(id->getSigGeneratorStdErr()));
}
else
sig=TQString();
return art;
}
bool KNArticleFactory::cancelAllowed(KNArticle *a)
{
if(!a)
return false;
if(a->type()==KMime::Base::ATlocal) {
KNLocalArticle *localArt=static_cast<KNLocalArticle*>(a);
if(localArt->doMail() && !localArt->doPost()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("Emails cannot be canceled or superseded."));
return false;
}
KMime::Headers::Control *ctrl=localArt->control(false);
if(ctrl && ctrl->isCancel()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("Cancel messages cannot be canceled or superseded."));
return false;
}
if(!localArt->posted()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("Only sent articles can be canceled or superseded."));
return false;
}
if(localArt->canceled()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("This article has already been canceled or superseded."));
return false;
}
KMime::Headers::MessageID *mid=localArt->messageID(false);
if(!mid || mid->isEmpty()) {
KMessageBox::sorry(knGlobals.topWidget, i18n(
"This article cannot be canceled or superseded,\n\
because its message-id has not been created by KNode.\n\
But you can look for your article in the newsgroup\n\
and cancel (or supersede) it there."));
return false;
}
return true;
}
else if(a->type()==KMime::Base::ATremote) {
KNRemoteArticle *remArt=static_cast<KNRemoteArticle*>(a);
KNGroup *g=static_cast<KNGroup*>(a->collection());
KNConfig::Identity *defId=knGlobals.configManager()->identity(),
*gid=g->identity(),
*accId=g->account()->identity();
bool ownArticle = false;
if (gid && gid->hasName())
ownArticle |= ( gid->name() == remArt->from()->name() );
if (accId && accId->hasName())
ownArticle |= ( accId->name() == remArt->from()->name() );
ownArticle |= ( defId->name() == remArt->from()->name() );
if(ownArticle) {
ownArticle = false;
if(gid && gid->hasEmail())
ownArticle |= ( gid->email().latin1() == remArt->from()->email() );
if (accId && accId->hasEmail())
ownArticle |= ( accId->email().latin1() == remArt->from()->email() );
ownArticle |= ( defId->email().latin1() == remArt->from()->email() );
}
if(!ownArticle) {
KMessageBox::sorry(knGlobals.topWidget, i18n("This article does not appear to be from you.\nYou can only cancel or supersede your own articles."));
return false;
}
if(!remArt->hasContent()) {
KMessageBox::sorry(knGlobals.topWidget, i18n("You have to download the article body\nbefore you can cancel or supersede the article."));
return false;
}
return true;
}
return false;
}
void KNArticleFactory::showSendErrorDialog()
{
if(!s_endErrDlg) {
s_endErrDlg=new KNSendErrorDialog();
connect(s_endErrDlg, TQT_SIGNAL(closeClicked()), this, TQT_SLOT(slotSendErrorDialogDone()));
}
s_endErrDlg->show();
}
void KNArticleFactory::slotComposerDone(KNComposer *com)
{
bool delCom=true;
KNLocalArticle::List lst;
lst.append(com->article());
switch(com->result()) {
case KNComposer::CRsendNow:
delCom=com->hasValidData();
if(delCom) {
if ( com->applyChanges() )
sendArticles( lst, true );
else
delCom = false;
}
break;
case KNComposer::CRsendLater:
delCom=com->hasValidData();
if(delCom) {
if ( com->applyChanges() )
sendArticles( lst, false );
else
delCom = false;
}
break;
case KNComposer::CRsave :
if ( com->applyChanges() )
knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->drafts());
break;
case KNComposer::CRdelAsk:
delCom=knGlobals.articleManager()->deleteArticles(lst, true);
break;
case KNComposer::CRdel:
delCom=knGlobals.articleManager()->deleteArticles(lst, false);
break;
case KNComposer::CRcancel:
// just close...
break;
default: break;
};
if ( delCom ) {
mCompList.remove( com );
delete com;
} else
KWin::activateWindow(com->winId());
}
void KNArticleFactory::slotSendErrorDialogDone()
{
s_endErrDlg->delayedDestruct();
s_endErrDlg=0;
}
//======================================================================================================
KNSendErrorDialog::KNSendErrorDialog()
: KDialogBase(knGlobals.topWidget, 0, true, i18n("Errors While Sending"), Close, Close, true)
{
p_ixmap=knGlobals.configManager()->appearance()->icon(KNConfig::Appearance::sendErr);
TQVBox *page = makeVBoxMainWidget();
new TQLabel(TQString("<b>%1</b><br>%2").arg(i18n("Errors occurred while sending these articles:"))
.arg(i18n("The unsent articles are stored in the \"Outbox\" folder.")), page);
j_obs=new KNDialogListBox(true, page);
e_rror=new TQLabel(TQString(), page);
connect(j_obs, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(slotHighlighted(int)));
KNHelper::restoreWindowSize("sendDlg", this, TQSize(320,250));
}
KNSendErrorDialog::~KNSendErrorDialog()
{
KNHelper::saveWindowSize("sendDlg", size());
}
void KNSendErrorDialog::append(const TQString &subject, const TQString &error)
{
LBoxItem *it=new LBoxItem(error, subject, &p_ixmap);
j_obs->insertItem(it);
j_obs->setCurrentItem(it);
}
void KNSendErrorDialog::slotHighlighted(int idx)
{
LBoxItem *it=static_cast<LBoxItem*>(j_obs->item(idx));
if(it) {
TQString tmp=i18n("<b>Error message:</b><br>")+it->error;
e_rror->setText(tmp);
}
}
//-------------------------------
#include "knarticlefactory.moc"
// kate: space-indent on; indent-width 2;