• Skip to content
  • Skip to link menu
KDE 4.5 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

knode

knarticlefactory.cpp

Go to the documentation of this file.
00001 /*
00002     KNode, the KDE newsreader
00003     Copyright (c) 1999-2006 the KNode authors.
00004     See file AUTHORS for details
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010     You should have received a copy of the GNU General Public License
00011     along with this program; if not, write to the Free Software Foundation,
00012     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
00013 */
00014 
00015 
00016 #include "knarticlefactory.h"
00017 
00018 #include "knglobals.h"
00019 #include "kngroupmanager.h"
00020 #include "knaccountmanager.h"
00021 #include "knfoldermanager.h"
00022 #include "knarticlemanager.h"
00023 #include "knfolder.h"
00024 #include "kncomposer.h"
00025 #include "knnntpaccount.h"
00026 #include "mailsendjob.h"
00027 #include "nntpjobs.h"
00028 #include "utilities.h"
00029 #include "resource.h"
00030 #include "settings.h"
00031 #include "utils/locale.h"
00032 
00033 #include <QByteArray>
00034 #include <QList>
00035 #include <QListWidget>
00036 #include <KPIMIdentities/Identity>
00037 #include <KPIMIdentities/IdentityManager>
00038 #include <KPIMUtils/Email>
00039 #include <QLabel>
00040 #include <kiconloader.h>
00041 #include <klocale.h>
00042 #include <kmessagebox.h>
00043 #include <kwindowsystem.h>
00044 #include <ktoolinvocation.h>
00045 #include <kvbox.h>
00046 #include <mailtransport/transportmanager.h>
00047 
00048 
00049 using namespace KNode;
00050 using namespace KNode::Utilities;
00051 using namespace MailTransport;
00052 
00053 KNArticleFactory::KNArticleFactory( QObject *parent )
00054   : QObject( parent ), s_endErrDlg(0)
00055 {
00056 }
00057 
00058 
00059 KNArticleFactory::~KNArticleFactory()
00060 {
00061   for ( QList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
00062     delete (*it);
00063   delete s_endErrDlg;
00064 }
00065 
00066 
00067 void KNArticleFactory::createPosting(KNNntpAccount *a)
00068 {
00069   if(!a)
00070     return;
00071 
00072   KPIMIdentities::Identity identity;
00073   KNLocalArticle *art = newArticle( a, Locale::defaultCharset() );
00074   if(!art)
00075     return;
00076 
00077   art->setServerId(a->id());
00078   art->setDoPost(true);
00079   art->setDoMail(false);
00080 
00081   KNComposer *c = new KNComposer( art, QString(), QString(), true, false, false, false );
00082   mCompList.append( c );
00083   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00084   c->show();
00085 }
00086 
00087 
00088 void KNArticleFactory::createPosting(KNGroup *g)
00089 {
00090   if(!g)
00091     return;
00092 
00093   QByteArray chset = Locale::defaultCharset( g );
00094 
00095   KPIMIdentities::Identity identity;
00096   KNLocalArticle *art = newArticle( g, chset );
00097 
00098   if(!art)
00099     return;
00100 
00101   art->setServerId(g->account()->id());
00102   art->setDoPost(true);
00103   art->setDoMail(false);
00104   art->newsgroups()->fromUnicodeString(g->groupname(), art->defaultCharset());
00105   KNComposer *c = new KNComposer( art, QString(), QString(), true, false, false, false );
00106   mCompList.append( c );
00107   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00108   c->show();
00109 }
00110 
00111 
00112 void KNArticleFactory::createReply(KNRemoteArticle *a, const QString &selectedText, bool post, bool mail)
00113 {
00114   if(!a)
00115     return;
00116 
00117   KNGroup *g=static_cast<KNGroup*>(a->collection());
00118 
00119   QByteArray chset;
00120   if ( knGlobals.settings()->useOwnCharset() ) {
00121     chset = Locale::defaultCharset( g );
00122   } else {
00123     chset = a->contentType()->charset();
00124   }
00125 
00126   //create new article
00127   KPIMIdentities::Identity identity;
00128   KNLocalArticle *art = newArticle( g, chset, true, a );
00129   if(!art)
00130     return;
00131 
00132   art->setServerId(g->account()->id());
00133   art->setDoPost(post);
00134   art->setDoMail(mail);
00135 
00136   //------------------------- <Headers> ----------------------------
00137 
00138   //subject
00139   QString subject=a->subject()->asUnicodeString();
00140   if ( subject.left(3).toUpper() != "RE:" )
00141     subject.prepend("Re: ");
00142   art->subject()->fromUnicodeString(subject, a->subject()->rfc2047Charset());
00143 
00144   //newsgroups
00145   KMime::Headers::FollowUpTo *fup2=a->followUpTo(false);
00146   if(fup2 && !fup2->isEmpty()) {
00147     if( ( fup2->as7BitString(false).toUpper()=="POSTER" ) ) { //Followup-To: poster
00148       if( post && // user wanted to reply by public posting?
00149           // ask the user if she wants to ignore this F'up-To: poster
00150           ( KMessageBox::Yes != KMessageBox::questionYesNo(knGlobals.topWidget,
00151             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?"), QString(), KGuiItem(i18n("Reply Public")), KGuiItem(i18n("Reply by Email"))) ))
00152       {
00153         art->setDoPost(false);
00154         art->setDoMail(true);
00155       }
00156       art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
00157     }
00158     else
00159       art->newsgroups()->from7BitString(fup2->as7BitString(false));
00160   }
00161   else
00162     art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
00163 
00164   //To
00165   KMime::Headers::ReplyTo *replyTo=a->replyTo(false);
00166   KMime::Types::Mailbox address;
00167   if(replyTo && !replyTo->isEmpty()) {
00168     foreach( const KMime::Types::Mailbox &mbox, replyTo->mailboxes() ) {
00169       art->to()->addAddress( mbox );
00170     }
00171   }
00172   else {
00173     KMime::Headers::From *from=a->from();
00174     foreach( const KMime::Types::Mailbox &mbox, from->mailboxes() ) {
00175       art->to()->addAddress( mbox );
00176     }
00177   }
00178 
00179   //References
00180   KMime::Headers::References *references=a->references(false);
00181   QByteArray refs;
00182   if (references)
00183     refs=references->as7BitString(false);
00184   else
00185     refs = "";
00186 
00187   art->references()->from7BitString(refs);
00188   art->references()->appendIdentifier(a->messageID()->as7BitString(false));
00189 
00190   //Mail-Copies-To
00191   bool authorDislikesMailCopies=false;
00192   bool authorWantsMailCopies=false;
00193   KMime::Headers::MailCopiesTo *mailCopiesTo=a->mailCopiesTo(false);
00194 
00195   if( mailCopiesTo && !mailCopiesTo->isEmpty() ) {
00196     authorDislikesMailCopies = mailCopiesTo->neverCopy();
00197     authorWantsMailCopies = mailCopiesTo->alwaysCopy();
00198     if (authorWantsMailCopies)         // warn the user
00199       KMessageBox::information( knGlobals.topWidget, i18n("The author requested a mail copy of your reply. (Mail-Copies-To header)"),
00200                                 QString(), "mailCopiesToWarning" );
00201     if ( authorWantsMailCopies && !mailCopiesTo->mailboxes().isEmpty() ) {
00202       art->to()->clear();
00203       foreach ( const KMime::Types::Mailbox &mbox, mailCopiesTo->mailboxes() ) {
00204         art->to()->addAddress( mbox );
00205       }
00206     }
00207   }
00208 
00209   //------------------------- </Headers> ---------------------------
00210 
00211   //--------------------------- <Body> -----------------------------
00212 
00213   // attribution line
00214   QString attribution = knGlobals.settings()->intro();
00215   QString name( a->from()->displayNames().join( ", ") );
00216   if ( name.isEmpty() && !a->from()->isEmpty() )
00217     name = QString::fromLatin1( a->from()->addresses().first() );
00218   attribution.replace(QRegExp("%NAME"),name);
00219   if ( !a->from()->isEmpty() )
00220     attribution.replace(QRegExp("%EMAIL"), QString::fromLatin1(a->from()->addresses().first()));
00221   attribution.replace( QRegExp("%DATE"), KGlobal::locale()->formatDateTime(a->date()->dateTime().toLocalZone().dateTime(), KLocale::LongDate) );
00222   QString msid = a->messageID()->identifier();
00223   attribution.replace( QRegExp("%MSIDX"), msid );
00224   attribution.replace( QRegExp("%MSID"), QLatin1Char('<') + msid + QLatin1Char('>') );
00225   attribution.replace(QRegExp("%GROUP"),g->groupname());
00226   attribution.replace(QRegExp("%L"),"\n");
00227   attribution+="\n\n";
00228 
00229   QString quoted=attribution;
00230   QString notRewraped;
00231   QStringList text;
00232   QStringList::Iterator line;
00233   bool incSig = knGlobals.settings()->includeSignature();
00234 
00235   if (selectedText.isEmpty()) {
00236     KMime::Content *tc = a->textContent();
00237     if(tc)
00238       text = tc->decodedText( true, knGlobals.settings()->removeTrailingNewlines() ).split( '\n' );
00239   }
00240   else
00241     text = selectedText.split('\n');
00242 
00243   for(line=text.begin(); line!=text.end(); ++line) {
00244     if(!incSig && (*line)=="-- ")
00245       break;
00246 
00247     if ((*line)[0]=='>')
00248       quoted += '>' + (*line) + '\n';  // second quote level without space
00249     else
00250       quoted += "> " +(*line) + '\n';
00251   }
00252 
00253   if ( knGlobals.settings()->rewrap() ) {  //rewrap original article
00254 
00255     notRewraped=quoted;     // store the original text in here, the user can request it in the composer
00256     quoted=attribution;
00257 
00258     quoted += KNHelper::rewrapStringList( text, knGlobals.settings()->maxLineLength(), '>', !incSig, false );
00259   }
00260 
00261   //-------------------------- </Body> -----------------------------
00262 
00263   if ( art->doMail() && knGlobals.settings()->useExternalMailer() ) {
00264     sendMailExternal(address.prettyAddress(), subject, quoted);
00265     art->setDoMail(false);
00266     if (!art->doPost()) {
00267       delete art;
00268       return;
00269     }
00270   }
00271 
00272   //open composer
00273   KNComposer *c=new KNComposer(art, quoted, notRewraped, true, authorDislikesMailCopies, authorWantsMailCopies);
00274   mCompList.append( c );
00275   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00276   c->show();
00277 }
00278 
00279 
00280 void KNArticleFactory::createForward(KNArticle *a)
00281 {
00282   if(!a)
00283     return;
00284 
00285   KMime::Headers::ContentType *ct=a->contentType();
00286   QByteArray chset;
00287   bool incAtt = ( !knGlobals.settings()->useExternalMailer() &&
00288                   ct->isMultipart() && ct->isSubtype("mixed") &&
00289                   KMessageBox::Yes == KMessageBox::questionYesNo(knGlobals.topWidget,
00290                   i18n("This article contains attachments. Do you want them to be forwarded as well?"), QString(), KGuiItem(i18n("Forward")), KGuiItem(i18n("Do Not Forward")))
00291                 );
00292 
00293   if ( knGlobals.settings()->useOwnCharset() )
00294     chset = Locale::defaultCharset();
00295   else
00296     chset = a->contentType()->charset();
00297 
00298   //create new article
00299   KPIMIdentities::Identity identity;
00300   KNLocalArticle *art = newArticle( knGlobals.groupManager()->currentGroup(), chset );
00301   if(!art)
00302     return;
00303 
00304   art->setDoPost(false);
00305   art->setDoMail(true);
00306 
00307   //------------------------- <Headers> ----------------------------
00308 
00309   //subject
00310   QString subject=("Fwd: "+a->subject()->asUnicodeString());
00311   art->subject()->fromUnicodeString(subject, a->subject()->rfc2047Charset());
00312 
00313   //------------------------- </Headers> ---------------------------
00314 
00315   //--------------------------- <Body> -----------------------------
00316 
00317   QString fwd = QString("\n--------------- %1\n\n").arg(i18n("Forwarded message (begin)"));
00318 
00319   fwd+=( i18n("Subject") + ": " + a->subject()->asUnicodeString() + '\n' );
00320   fwd+=( i18n("From") + ": " + a->from()->asUnicodeString() + '\n' );
00321   fwd+=( i18n("Date") + ": " + a->date()->asUnicodeString() + '\n' );
00322   fwd+=( i18n("Newsgroup") + ": " + a->newsgroups()->asUnicodeString() + "\n\n" );
00323 
00324   KMime::Content *text=a->textContent();
00325   if(text)
00326     fwd += text->decodedText( false, false );
00327 
00328   fwd += QString("\n--------------- %1\n").arg(i18n("Forwarded message (end)"));
00329 
00330   //--------------------------- </Body> ----------------------------
00331 
00332 
00333   //------------------------ <Attachments> -------------------------
00334 
00335   if(incAtt) {
00336     KMime::Content::List al = a->attachments( false );
00337     foreach ( KMime::Content *c, al )
00338       art->addContent( new KMime::Content(c->head(), c->body()) );
00339   }
00340 
00341   //------------------------ </Attachments> ------------------------
00342 
00343 
00344   if ( knGlobals.settings()->useExternalMailer() ) {
00345     sendMailExternal( QString(), subject, fwd );
00346     delete art;
00347     return;
00348   }
00349 
00350   //open composer
00351   KNComposer *c = new KNComposer( art, fwd, QString(), true );
00352   mCompList.append( c );
00353   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00354   c->show();
00355 }
00356 
00357 
00358 void KNArticleFactory::createCancel(KNArticle *a)
00359 {
00360   if(!cancelAllowed(a))
00361     return;
00362 
00363   if( KMessageBox::No == KMessageBox::questionYesNo( knGlobals.topWidget,
00364       i18n("Do you really want to cancel this article?"), QString(), KGuiItem(i18n("Cancel Article")), KStandardGuiItem::cancel() ) )
00365     return;
00366 
00367   bool sendNow;
00368   switch (KMessageBox::warningYesNoCancel(knGlobals.topWidget, i18n("Do you want to send the cancel\nmessage now or later?"), i18n("Question"),KGuiItem(i18n("&Now")),KGuiItem(i18n("&Later")))) {
00369     case KMessageBox::Yes : sendNow = true; break;
00370     case KMessageBox::No :  sendNow = false; break;
00371     default :               return;
00372   }
00373 
00374   KNGroup *grp = 0;
00375   KNNntpAccount *nntp=0;
00376 
00377   if ( a->type() == KNArticle::ATremote )
00378     nntp=(static_cast<KNGroup*>(a->collection()))->account();
00379   else {
00380     if(!nntp)
00381       nntp=knGlobals.accountManager()->first();
00382     if(!nntp) {
00383       KMessageBox::error(knGlobals.topWidget, i18n("You have no valid news accounts configured."));
00384       return;
00385     }
00386     KNLocalArticle *la=static_cast<KNLocalArticle*>(a);
00387     la->setCanceled(true);
00388     la->updateListItem();
00389     nntp=knGlobals.accountManager()->account(la->serverId());
00390   }
00391 
00392   if ( !a->newsgroups()->isEmpty() )
00393     grp = knGlobals.groupManager()->group(a->newsgroups()->groups().first(), nntp);
00394 
00395   KPIMIdentities::Identity identity;
00396   KNLocalArticle *art = newArticle( grp, "us-ascii", false );
00397   if(!art)
00398     return;
00399 
00400   //init
00401   art->setDoPost(true);
00402   art->setDoMail(false);
00403 
00404   //server
00405   art->setServerId(nntp->id());
00406 
00407   //subject
00408   KMime::Headers::MessageID *msgId=a->messageID();
00409   QByteArray tmp;
00410   tmp="cancel of "+msgId->as7BitString(false);
00411   art->subject()->from7BitString(tmp);
00412 
00413   //newsgroups
00414   art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
00415 
00416   //control
00417   tmp="cancel "+msgId->as7BitString(false);
00418   art->control()->from7BitString(tmp);
00419 
00420   //Lines
00421   art->lines()->setNumberOfLines(1);
00422 
00423   //body
00424   art->fromUnicodeString(QString::fromLatin1("cancel by original author\n"));
00425 
00426   //assemble
00427   art->assemble();
00428 
00429   //send
00430   KNLocalArticle::List lst;
00431   lst.append(art);
00432   sendArticles( lst, sendNow );
00433 }
00434 
00435 
00436 void KNArticleFactory::createSupersede(KNArticle *a)
00437 {
00438   if (!a)
00439     return;
00440 
00441   if(!cancelAllowed(a))
00442     return;
00443 
00444   if ( KMessageBox::No==KMessageBox::questionYesNo( knGlobals.topWidget,
00445        i18n("Do you really want to supersede this article?"), QString(), KGuiItem(i18n("Supersede")), KStandardGuiItem::cancel() ) )
00446     return;
00447 
00448   KNGroup *grp = 0;
00449   KNNntpAccount *nntp;
00450 
00451   if ( a->type() == KNArticle::ATremote )
00452     nntp=(static_cast<KNGroup*>(a->collection()))->account();
00453   else {
00454     KNLocalArticle *la=static_cast<KNLocalArticle*>(a);
00455     la->setCanceled(true);
00456     la->updateListItem();
00457     nntp=knGlobals.accountManager()->account(la->serverId());
00458     if(!nntp)
00459       nntp=knGlobals.accountManager()->first();
00460     if(!nntp) {
00461       KMessageBox::error(knGlobals.topWidget, i18n("You have no valid news accounts configured."));
00462       return;
00463     }
00464   }
00465 
00466   if ( !a->newsgroups()->isEmpty() )
00467     grp = knGlobals.groupManager()->group(a->newsgroups()->groups().first(), nntp);
00468 
00469   //new article
00470   KPIMIdentities::Identity identity;
00471   KNLocalArticle *art = newArticle( grp, a->contentType()->charset() );
00472   if(!art)
00473     return;
00474 
00475   art->setDoPost(true);
00476   art->setDoMail(false);
00477 
00478   //server
00479   art->setServerId(nntp->id());
00480 
00481   //subject
00482   art->subject()->fromUnicodeString(a->subject()->asUnicodeString(), a->subject()->rfc2047Charset());
00483 
00484   //newsgroups
00485   art->newsgroups()->from7BitString(a->newsgroups()->as7BitString(false));
00486 
00487   //followup-to
00488   art->followUpTo()->from7BitString(a->followUpTo()->as7BitString(false));
00489 
00490   //References
00491   if ( !a->references()->isEmpty() )
00492     art->references()->from7BitString( a->references()->as7BitString(false) );
00493 
00494   //Supersedes
00495   art->supersedes()->from7BitString(a->messageID()->as7BitString(false));
00496 
00497   //Body
00498   QString text;
00499   KMime::Content *textContent=a->textContent();
00500   if(textContent)
00501     text = textContent->decodedText();
00502 
00503   //open composer
00504   KNComposer *c=new KNComposer(art, text);
00505   mCompList.append( c );
00506   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00507   c->show();
00508 }
00509 
00510 
00511 void KNArticleFactory::createMail(KMime::Types::Mailbox *address)
00512 {
00513   if ( knGlobals.settings()->useExternalMailer() ) {
00514     sendMailExternal(address->prettyAddress());
00515     return;
00516   }
00517 
00518   //create new article
00519   KPIMIdentities::Identity identity;
00520   KNLocalArticle *art = newArticle( knGlobals.groupManager()->currentGroup(), Locale::defaultCharset() );
00521   if(!art)
00522     return;
00523 
00524   art->setDoMail(true);
00525   art->setDoPost(false);
00526   art->to()->addAddress((*address));
00527 
00528   //open composer
00529   KNComposer *c = new KNComposer( art, QString(), QString(), true );
00530   mCompList.append( c );
00531   connect(c, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00532   c->show();
00533 }
00534 
00535 
00536 void KNArticleFactory::sendMailExternal(const QString &address, const QString &subject, const QString &body)
00537 {
00538   KUrl mailtoURL;
00539   QStringList queries;
00540   QString query;
00541   mailtoURL.setProtocol("mailto");
00542 
00543   if (!address.isEmpty())
00544     mailtoURL.setPath(address);
00545   if (!subject.isEmpty())
00546     queries.append("subject="+KUrl::toPercentEncoding(subject));
00547   if (!body.isEmpty())
00548     queries.append("body="+KUrl::toPercentEncoding(body));
00549 
00550   if (queries.count() > 0) {
00551     query = '?';
00552     for ( QStringList::Iterator it = queries.begin(); it != queries.end(); ++it ) {
00553       if (it != queries.begin())
00554         query.append( '&' );
00555       query.append((*it));
00556     }
00557   }
00558 
00559   if (!query.isEmpty())
00560     mailtoURL.setQuery(query);
00561 
00562   KToolInvocation::invokeMailer(mailtoURL);
00563 }
00564 
00565 
00566 void KNArticleFactory::edit(KNLocalArticle *a)
00567 {
00568   if(!a)
00569     return;
00570 
00571   KNComposer *com=findComposer(a);
00572   if(com) {
00573 #ifdef Q_OS_UNIX
00574     KWindowSystem::activateWindow(com->winId());
00575 #endif
00576     return;
00577   }
00578 
00579   if(a->editDisabled()) {
00580     KMessageBox::sorry(knGlobals.topWidget, i18n("This article cannot be edited."));
00581     return;
00582   }
00583 
00584   //find identity
00585   KPIMIdentities::Identity id = KNGlobals::self()->settings()->identity();
00586 
00587   if(a->doPost()) {
00588     KNNntpAccount *acc=knGlobals.accountManager()->account(a->serverId());
00589     if(acc) {
00590       KMime::Headers::Newsgroups *grps=a->newsgroups();
00591       if ( !grps->isEmpty() ) {
00592         KNGroup *grp = knGlobals.groupManager()->group(grps->groups().first(), acc);
00593         if ( grp && !grp->identity().isNull() ) {
00594           id = grp->identity();
00595         } else if ( !acc->identity().isNull() ) {
00596           id = acc->identity();
00597         }
00598       }
00599     }
00600   }
00601 
00602   //load article body
00603   if(!a->hasContent())
00604     knGlobals.articleManager()->loadArticle(a);
00605 
00606   //open composer
00607   com = new KNComposer( a, QString() );
00608   mCompList.append( com );
00609   connect(com, SIGNAL(composerDone(KNComposer*)), this, SLOT(slotComposerDone(KNComposer*)));
00610   com->show();
00611 }
00612 
00613 
00614 void KNArticleFactory::sendArticles( KNLocalArticle::List &l, bool now )
00615 {
00616   KNJobData *job=0;
00617   KNServerInfo *ser=0;
00618 
00619   KNLocalArticle::List unsent, sent;
00620   for ( KNLocalArticle::List::Iterator it = l.begin(); it != l.end(); ++it ) {
00621     if ( (*it)->pending() )
00622       unsent.append( (*it) );
00623     else
00624       sent.append( (*it) );
00625   }
00626 
00627   if(!sent.isEmpty()) {
00628     showSendErrorDialog();
00629     for ( KNLocalArticle::List::Iterator it = sent.begin(); it != sent.end(); ++it )
00630       s_endErrDlg->append( (*it)->subject()->asUnicodeString(), i18n("Article has already been sent.") );
00631   }
00632 
00633   if(!now) {
00634     knGlobals.articleManager()->moveIntoFolder(unsent, knGlobals.folderManager()->outbox());
00635     return;
00636   }
00637 
00638 
00639   for ( KNLocalArticle::List::Iterator it = unsent.begin(); it != unsent.end(); ++it ) {
00640 
00641     if ( (*it)->isLocked() )
00642       continue;
00643 
00644     if ( !(*it)->hasContent() ) {
00645       if ( !knGlobals.articleManager()->loadArticle( (*it) ) ) {
00646         showSendErrorDialog();
00647         s_endErrDlg->append( (*it)->subject()->asUnicodeString(), i18n("Unable to load article.") );
00648         continue;
00649       }
00650     }
00651 
00652 
00653     // filter out internal headers
00654     QByteArray head = (*it)->head();
00655     KMime::Headers::Base *header = 0;
00656     while ( true ) {
00657       header = KMime::HeaderParsing::extractFirstHeader( head );
00658       if ( !header ) {
00659         break;
00660       }
00661       if ( qstrncmp( header->type(), "X-KNode", 7 ) == 0 ) {
00662         (*it)->removeHeader( header->type() );
00663       }
00664     }
00665     (*it)->assemble(); // Validate change made above
00666 
00667 
00668     if ( (*it)->doPost() && !(*it)->posted() ) {
00669       ser = knGlobals.accountManager()->account( (*it)->serverId() );
00670       job = new ArticlePostJob( this, ser, (*it) );
00671       emitJob(job);
00672     }
00673     if ( (*it)->doMail() && !(*it)->mailed() ) {
00674       int transportId = TransportManager::self()->defaultTransportId();
00675       job = new MailSendJob( this, transportId, (*it) );
00676       emitJob(job);
00677     }
00678   }
00679 }
00680 
00681 
00682 void KNArticleFactory::sendOutbox()
00683 {
00684   KNLocalArticle::List lst;
00685   KNFolder *ob=0;
00686 
00687   if(!knGlobals.folderManager()->loadOutbox()) {
00688     KMessageBox::error(knGlobals.topWidget, i18n("Unable to load the outbox-folder."));
00689     return;
00690   }
00691 
00692   ob=knGlobals.folderManager()->outbox();
00693   for(int i=0; i< ob->length(); i++)
00694     lst.append(ob->at(i));
00695 
00696   sendArticles( lst, true );
00697 }
00698 
00699 
00700 bool KNArticleFactory::closeComposeWindows()
00701 {
00702   while ( !mCompList.isEmpty() ) {
00703     QList<KNComposer*>::Iterator it = mCompList.begin();
00704     if ( !(*it)->close() )
00705       return false;
00706   }
00707 
00708   return true;
00709 }
00710 
00711 
00712 void KNArticleFactory::deleteComposerForArticle(KNLocalArticle *a)
00713 {
00714   KNComposer *com = findComposer( a );
00715   if ( com ) {
00716     mCompList.removeAll( com );
00717     com->deleteLater();
00718   }
00719 }
00720 
00721 
00722 KNComposer* KNArticleFactory::findComposer(KNLocalArticle *a)
00723 {
00724   for ( QList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
00725     if ( (*it)->article() == a )
00726       return (*it);
00727   return 0;
00728 }
00729 
00730 
00731 void KNArticleFactory::configChanged()
00732 {
00733   for ( QList<KNComposer*>::Iterator it = mCompList.begin(); it != mCompList.end(); ++it )
00734     (*it)->setConfig( false );
00735 }
00736 
00737 
00738 void KNArticleFactory::processJob(KNJobData *j)
00739 {
00740   KNLocalArticle *art=static_cast<KNLocalArticle*>(j->data());
00741   KNLocalArticle::List lst;
00742   lst.append(art);
00743 
00744   if(j->canceled()) {
00745     delete j;
00746 
00747     //sending of this article was canceled => move it to the "Outbox-Folder"
00748     if(art->collection()!=knGlobals.folderManager()->outbox())
00749       knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->outbox());
00750 
00751     KMessageBox::information(knGlobals.topWidget, i18n("You canceled the article posting. The unsent articles are stored in the \"Outbox\" folder."));
00752 
00753     return;
00754   }
00755 
00756   if(!j->success()) {
00757     showSendErrorDialog();
00758     s_endErrDlg->append(art->subject()->asUnicodeString(), j->errorString());
00759     delete j; //unlock article
00760 
00761     //sending of this article failed => move it to the "Outbox-Folder"
00762     if(art->collection()!=knGlobals.folderManager()->outbox())
00763       knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->outbox());
00764   }
00765   else {
00766 
00767     //disable edit
00768     art->setEditDisabled(true);
00769 
00770     switch(j->type()) {
00771 
00772       case KNJobData::JTpostArticle:
00773         delete j; //unlock article
00774         art->setPosted(true);
00775         if(art->doMail() && !art->mailed()) { //article has been posted, now mail it
00776           sendArticles( lst, true );
00777           return;
00778         }
00779       break;
00780 
00781       case KNJobData::JTmail:
00782         delete j; //unlock article
00783         art->setMailed(true);
00784       break;
00785 
00786       default: break;
00787     };
00788 
00789     //article has been sent successfully => move it to the "Sent-folder"
00790     knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->sent());
00791   }
00792 }
00793 
00794 
00795 KNLocalArticle* KNArticleFactory::newArticle( KNCollection *col, const QByteArray &defChset, bool withXHeaders, KNArticle *origPost )
00796 {
00797   if ( knGlobals.settings()->generateMessageID() && knGlobals.settings()->hostname().isEmpty() ) {
00798     KMessageBox::sorry(knGlobals.topWidget, i18n("Please set a hostname for the generation\nof the message-id or disable it."));
00799     return 0;
00800   }
00801 
00802   KNLocalArticle *art=new KNLocalArticle(0);
00803   KPIMIdentities::Identity id;
00804   if (col) {
00805     if (col->type() == KNCollection::CTgroup) {
00806       id = (static_cast<KNGroup *>(col))->identity();
00807       if ( id.isNull() ) {
00808         id = (static_cast<KNGroup *>(col))->account()->identity();
00809       }
00810     } else if (col->type() == KNCollection::CTnntpAccount) {
00811       id = (static_cast<KNNntpAccount *>(col))->identity();
00812     }
00813   }
00814   if ( id.isNull() ) {
00815     id = KNGlobals::self()->settings()->identity();
00816   }
00817   // Identity UOID
00818   KMime::Headers::Generic *xKnodeIdentity = new KMime::Headers::Generic( "X-KNode-Identity",
00819                                                                          art,
00820                                                                          QByteArray::number( id.uoid() ) );
00821   art->setHeader( xKnodeIdentity );
00822 
00823   //Message-id
00824   if ( knGlobals.settings()->generateMessageID() )
00825     art->messageID()->generate( knGlobals.settings()->hostname().toLatin1() );
00826 
00827   //From
00828   KMime::Headers::From *from=art->from();
00829   if ( KPIMUtils::isValidSimpleAddress( id.emailAddr() ) ) {
00830     from->fromUnicodeString( id.fullEmailAddr(), Locale::defaultCharset() );
00831   } else {
00832     KMessageBox::sorry( knGlobals.topWidget,
00833                         i18n( "<qt>Please enter a valid email address for the "
00834                               "identity named <emphasis>%1</emphasis> "
00835                               "at the identity section of the configuration dialog.</qt>",
00836                               id.identityName() ) );
00837     delete art;
00838     return 0;
00839   }
00840 
00841   //Reply-To
00842   if ( KPIMUtils::isValidAddress( id.replyToAddr() ) == KPIMUtils::AddressOk ) {
00843     art->replyTo()->fromUnicodeString( id.replyToAddr(), Locale::defaultCharset() );
00844   } else {
00845     art->removeHeader( "Reply-To" );
00846   }
00847 
00848   //Mail-Copies-To
00849   if ( KPIMUtils::isValidAddress( id.property( "Mail-Copies-To" ).toString() ) == KPIMUtils::AddressOk ) {
00850     art->mailCopiesTo()->fromUnicodeString( id.property( "Mail-Copies-To" ).toString(), Locale::defaultCharset() );
00851   } else {
00852     art->removeHeader( "Mail-Copies-To" );
00853   }
00854 
00855   //Organization
00856   if ( !id.organization().trimmed().isEmpty() ) {
00857     art->organization()->fromUnicodeString( id.organization(), Locale::defaultCharset() );
00858   } else {
00859     art->removeHeader( "Organization" );
00860   }
00861 
00862   //Date
00863   art->date()->setDateTime( KDateTime::currentLocalDateTime() );
00864 
00865   //User-Agent
00866   if( !knGlobals.settings()->noUserAgent() ) {
00867     art->userAgent()->from7BitString("KNode/" KNODE_VERSION);
00868   }
00869 
00870   //Mime
00871   KMime::Headers::ContentType *type=art->contentType();
00872   type->setMimeType("text/plain");
00873 
00874   type->setCharset(defChset);
00875 
00876   if ( defChset.toLower() == "us-ascii"  )
00877     art->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
00878   else
00879     art->contentTransferEncoding()->setEncoding( knGlobals.settings()->allow8BitBody() ? KMime::Headers::CE8Bit : KMime::Headers::CEquPr );
00880 
00881   //X-Headers
00882   if(withXHeaders) {
00883     XHeader::List xhdr = knGlobals.settings()->xHeaders();
00884     for ( XHeader::List::Iterator it = xhdr.begin(); it != xhdr.end(); ++it ) {
00885       QString value = (*it).value();
00886       if(origPost) {
00887         QString name( origPost->from()->displayNames().join(", ") );
00888         if ( name.isEmpty() && !origPost->from()->isEmpty() )
00889           name = QString::fromLatin1( origPost->from()->addresses().first() );
00890         value.replace(QRegExp("%NAME"), name);
00891         if ( !origPost->from()->isEmpty() )
00892           value.replace( QRegExp("%EMAIL"), QString::fromLatin1(origPost->from()->addresses().first() ) );
00893       }
00894       else
00895         if ( value.indexOf( "%NAME" ) != -1 || value.indexOf( "%EMAIL" ) != -1 )
00896           continue;
00897 
00898       art->setHeader( new KMime::Headers::Generic( (*it).name().toLatin1(), art, value,
00899                       Locale::defaultCharset() ) );
00900     }
00901   }
00902 
00903   return art;
00904 }
00905 
00906 
00907 bool KNArticleFactory::cancelAllowed(KNArticle *a)
00908 {
00909   if(!a)
00910     return false;
00911 
00912   if(a->type()==KNArticle::ATlocal) {
00913     KNLocalArticle *localArt=static_cast<KNLocalArticle*>(a);
00914 
00915     if(localArt->doMail() && !localArt->doPost()) {
00916       KMessageBox::sorry(knGlobals.topWidget, i18n("Emails cannot be canceled or superseded."));
00917       return false;
00918     }
00919 
00920     KMime::Headers::Control *ctrl=localArt->control(false);
00921     if(ctrl && ctrl->isCancel()) {
00922       KMessageBox::sorry(knGlobals.topWidget, i18n("Cancel messages cannot be canceled or superseded."));
00923       return false;
00924     }
00925 
00926     if(!localArt->posted()) {
00927       KMessageBox::sorry(knGlobals.topWidget, i18n("Only sent articles can be canceled or superseded."));
00928       return false;
00929     }
00930 
00931     if(localArt->canceled()) {
00932       KMessageBox::sorry(knGlobals.topWidget, i18n("This article has already been canceled or superseded."));
00933       return false;
00934     }
00935 
00936     KMime::Headers::MessageID *mid=localArt->messageID(false);
00937     if(!mid || mid->isEmpty()) {
00938       KMessageBox::sorry(knGlobals.topWidget, i18n(
00939 "This article cannot be canceled or superseded,\n\
00940 because its message-id has not been created by KNode.\n\
00941 But you can look for your article in the newsgroup\n\
00942 and cancel (or supersede) it there."));
00943       return false;
00944     }
00945 
00946     return true;
00947   }
00948   else if ( a->type() == KNArticle::ATremote ) {
00949 
00950     KNRemoteArticle *remArt=static_cast<KNRemoteArticle*>(a);
00951 
00952     KPIMIdentities::IdentityManager *im = KNGlobals::self()->identityManager();
00953     bool ownArticle = false;
00954     const QList<QByteArray> fromAddr = remArt->from()->addresses();
00955     foreach ( const QByteArray &addr, fromAddr ) {
00956       if ( im->thatIsMe( QString::fromLatin1( addr ) ) ) {
00957         ownArticle = true;
00958         break;
00959       }
00960     }
00961     if(!ownArticle) {
00962       KMessageBox::sorry(knGlobals.topWidget, i18n("This article does not appear to be from you.\nYou can only cancel or supersede your own articles."));
00963       return false;
00964     }
00965 
00966     if(!remArt->hasContent())  {
00967       KMessageBox::sorry(knGlobals.topWidget, i18n("You have to download the article body\nbefore you can cancel or supersede the article."));
00968       return false;
00969     }
00970 
00971     return true;
00972   }
00973 
00974   return false;
00975 }
00976 
00977 
00978 void KNArticleFactory::showSendErrorDialog()
00979 {
00980   if(!s_endErrDlg) {
00981     s_endErrDlg=new KNSendErrorDialog();
00982     connect(s_endErrDlg, SIGNAL(closeClicked()), this, SLOT(slotSendErrorDialogDone()));
00983   }
00984   s_endErrDlg->show();
00985 }
00986 
00987 
00988 void KNArticleFactory::slotComposerDone(KNComposer *com)
00989 {
00990   bool delCom=true;
00991   KNLocalArticle::List lst;
00992   lst.append(com->article());
00993 
00994   switch(com->result()) {
00995 
00996     case KNComposer::CRsendNow:
00997       delCom=com->hasValidData();
00998       if(delCom) {
00999         if ( com->applyChanges() )
01000           sendArticles( lst, true );
01001         else
01002           delCom = false;
01003       }
01004     break;
01005 
01006     case KNComposer::CRsendLater:
01007       delCom=com->hasValidData();
01008       if(delCom) {
01009         if ( com->applyChanges() )
01010           sendArticles( lst, false );
01011         else
01012           delCom = false;
01013       }
01014     break;
01015 
01016     case KNComposer::CRsave :
01017       com->applyChanges();
01018       knGlobals.articleManager()->moveIntoFolder(lst, knGlobals.folderManager()->drafts());
01019     break;
01020 
01021     case KNComposer::CRdelAsk:
01022       delCom=knGlobals.articleManager()->deleteArticles(lst, true);
01023     break;
01024 
01025     case KNComposer::CRdel:
01026       delCom=knGlobals.articleManager()->deleteArticles(lst, false);
01027     break;
01028 
01029     case KNComposer::CRcancel:
01030       // just close...
01031     break;
01032 
01033     default: break;
01034 
01035   };
01036 
01037   if ( delCom ) {
01038     mCompList.removeAll( com );
01039     com->deleteLater();
01040   }
01041 #ifdef Q_OS_UNIX
01042   else
01043     KWindowSystem::activateWindow(com->winId());
01044 #endif
01045 }
01046 
01047 
01048 void KNArticleFactory::slotSendErrorDialogDone()
01049 {
01050   s_endErrDlg->deleteLater();
01051   s_endErrDlg=0;
01052 }
01053 
01054 
01055 //======================================================================================================
01056 
01057 
01058 KNSendErrorDialog::KNSendErrorDialog()
01059   : KDialog( knGlobals.topWidget )
01060 {
01061   setCaption( i18n("Errors While Sending") );
01062   setButtons( Close );
01063   KVBox *page = new KVBox( this );
01064   setMainWidget( page );
01065   setDefaultButton( Close );
01066 
01067   new QLabel(QString("<b>%1</b><br>%2").arg(i18n("Errors occurred while sending these articles:"))
01068                                        .arg(i18n("The unsent articles are stored in the \"Outbox\" folder.")), page);
01069   mErrorList = new QListWidget( page );
01070   mError = new QLabel( QString(), page );
01071   mError->setWordWrap( true );
01072 
01073   connect( mErrorList, SIGNAL( currentRowChanged( int ) ), SLOT( slotHighlighted( int ) ) );
01074 
01075   KNHelper::restoreWindowSize("sendDlg", this, QSize(320,250));
01076 }
01077 
01078 
01079 KNSendErrorDialog::~KNSendErrorDialog()
01080 {
01081   KNHelper::saveWindowSize("sendDlg", size());
01082 }
01083 
01084 
01085 void KNSendErrorDialog::append(const QString &subject, const QString &error)
01086 {
01087   ErrorListItem *item = new ErrorListItem( subject, error );
01088   item->setIcon( UserIcon("snderr") );
01089   mErrorList->addItem( item );
01090   mErrorList->setCurrentItem( item );
01091 }
01092 
01093 
01094 void KNSendErrorDialog::slotHighlighted(int idx)
01095 {
01096   ErrorListItem *item = static_cast<ErrorListItem*>( mErrorList->item( idx ) );
01097   if ( item ) {
01098     QString tmp = i18n("<b>Error message:</b><br />") + item->error();
01099     mError->setText( tmp );
01100   }
01101 }
01102 
01103 //-------------------------------
01104 #include "knarticlefactory.moc"

knode

Skip menu "knode"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdepim

Skip menu "kdepim"
  •   akonadi_next
  •   kcal
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korganizer
  •   korgac
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • messageviewer
  • runtime
  •   kcm
  •       libmaildir
Generated for kdepim by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal