00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <qstring.h>
00024 #include <qdatetime.h>
00025 #include <klocale.h>
00026 #include <kcalendarsystem.h>
00027 #include <kmime_util.h>
00028 #include <kglobal.h>
00029 #include <kprocess.h>
00030 #include <qregexp.h>
00031 #include <qfile.h>
00032 #include <kmessagebox.h>
00033 #include <kshell.h>
00034 #include <qfileinfo.h>
00035
00036 #include "kmmessage.h"
00037 #include "kmmsgbase.h"
00038 #include "kmfolder.h"
00039 #include "templatesconfiguration.h"
00040 #include "templatesconfiguration_kfg.h"
00041 #include "customtemplates_kfg.h"
00042 #include "globalsettings_base.h"
00043 #include "kmkernel.h"
00044 #include <libkpimidentities/identity.h>
00045 #include <libkpimidentities/identitymanager.h>
00046 #include "partNode.h"
00047 #include "attachmentcollector.h"
00048 #include "objecttreeparser.h"
00049
00050 #include "templateparser.h"
00051 #include <mimelib/bodypart.h>
00052
00053 TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode,
00054 const QString aselection,
00055 bool asmartQuote, bool anoQuote,
00056 bool aallowDecryption, bool aselectionIsBody ) :
00057 mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSelection( aselection ),
00058 mSmartQuote( asmartQuote ), mNoQuote( anoQuote ),
00059 mAllowDecryption( aallowDecryption ), mSelectionIsBody( aselectionIsBody ),
00060 mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 )
00061 {
00062 mMsg = amsg;
00063 }
00064
00065 TemplateParser::~TemplateParser()
00066 {
00067 delete mOrigRoot;
00068 mOrigRoot = 0;
00069 }
00070
00071 int TemplateParser::parseQuotes( const QString &prefix, const QString &str,
00072 QString "e ) const
00073 {
00074 int pos = prefix.length();
00075 int len;
00076 int str_len = str.length();
00077 QChar qc = '"';
00078 QChar prev = 0;
00079
00080 pos++;
00081 len = pos;
00082
00083 while ( pos < str_len ) {
00084 QChar c = str[pos];
00085
00086 pos++;
00087 len++;
00088
00089 if ( prev ) {
00090 quote.append( c );
00091 prev = 0;
00092 } else {
00093 if ( c == '\\' ) {
00094 prev = c;
00095 } else if ( c == qc ) {
00096 break;
00097 } else {
00098 quote.append( c );
00099 }
00100 }
00101 }
00102
00103 return len;
00104 }
00105
00106 QString TemplateParser::getFName( const QString &str )
00107 {
00108
00109
00110
00111
00112 int sep_pos;
00113 QString res;
00114 if ( ( sep_pos = str.find( '@' ) ) > 0 ) {
00115 int i;
00116 for ( i = (sep_pos - 1); i >= 0; --i ) {
00117 QChar c = str[i];
00118 if ( c.isLetterOrNumber() ) {
00119 res.prepend( c );
00120 } else {
00121 break;
00122 }
00123 }
00124 } else if ( ( sep_pos = str.find(',') ) > 0 ) {
00125 unsigned int i;
00126 bool begin = false;
00127 for ( i = sep_pos; i < str.length(); ++i ) {
00128 QChar c = str[i];
00129 if ( c.isLetterOrNumber() ) {
00130 begin = true;
00131 res.append( c );
00132 } else if ( begin ) {
00133 break;
00134 }
00135 }
00136 } else {
00137 unsigned int i;
00138 for ( i = 0; i < str.length(); ++i ) {
00139 QChar c = str[i];
00140 if ( c.isLetterOrNumber() ) {
00141 res.append( c );
00142 } else {
00143 break;
00144 }
00145 }
00146 }
00147 return res;
00148 }
00149
00150 QString TemplateParser::getLName( const QString &str )
00151 {
00152
00153
00154
00155 int sep_pos;
00156 QString res;
00157 if ( ( sep_pos = str.find(',') ) > 0 ) {
00158 int i;
00159 for ( i = sep_pos; i >= 0; --i ) {
00160 QChar c = str[i];
00161 if ( c.isLetterOrNumber() ) {
00162 res.prepend( c );
00163 } else {
00164 break;
00165 }
00166 }
00167 } else {
00168 if ( ( sep_pos = str.find( ' ' ) ) > 0 ) {
00169 unsigned int i;
00170 bool begin = false;
00171 for ( i = sep_pos; i < str.length(); ++i ) {
00172 QChar c = str[i];
00173 if ( c.isLetterOrNumber() ) {
00174 begin = true;
00175 res.append( c );
00176 } else if ( begin ) {
00177 break;
00178 }
00179 }
00180 }
00181 }
00182 return res;
00183 }
00184
00185 void TemplateParser::process( KMMessage *aorig_msg, KMFolder *afolder, bool append )
00186 {
00187 mAppend = append;
00188 mOrigMsg = aorig_msg;
00189 mFolder = afolder;
00190 QString tmpl = findTemplate();
00191 return processWithTemplate( tmpl );
00192 }
00193
00194 void TemplateParser::process( const QString &tmplName, KMMessage *aorig_msg,
00195 KMFolder *afolder, bool append )
00196 {
00197 mAppend = append;
00198 mOrigMsg = aorig_msg;
00199 mFolder = afolder;
00200 QString tmpl = findCustomTemplate( tmplName );
00201 return processWithTemplate( tmpl );
00202 }
00203
00204 void TemplateParser::processWithTemplate( const QString &tmpl )
00205 {
00206 QString body;
00207 int tmpl_len = tmpl.length();
00208 bool dnl = false;
00209 for ( int i = 0; i < tmpl_len; ++i ) {
00210 QChar c = tmpl[i];
00211
00212 if ( c == '%' ) {
00213 QString cmd = tmpl.mid( i + 1 );
00214
00215 if ( cmd.startsWith( "-" ) ) {
00216
00217 kdDebug() << "Command: -" << endl;
00218 dnl = true;
00219 i += 1;
00220
00221 } else if ( cmd.startsWith( "REM=" ) ) {
00222
00223 kdDebug() << "Command: REM=" << endl;
00224 QString q;
00225 int len = parseQuotes( "REM=", cmd, q );
00226 i += len;
00227
00228 } else if ( cmd.startsWith( "INSERT=" ) ) {
00229
00230 kdDebug() << "Command: INSERT=" << endl;
00231 QString q;
00232 int len = parseQuotes( "INSERT=", cmd, q );
00233 i += len;
00234 QString path = KShell::tildeExpand( q );
00235 QFileInfo finfo( path );
00236 if (finfo.isRelative() ) {
00237 path = KShell::homeDir( "" );
00238 path += '/';
00239 path += q;
00240 }
00241 QFile file( path );
00242 if ( file.open( IO_ReadOnly ) ) {
00243 QByteArray content = file.readAll();
00244 QString str = QString::fromLocal8Bit( content, content.size() );
00245 body.append( str );
00246 } else if ( mDebug ) {
00247 KMessageBox::error( 0,
00248 i18n( "Cannot insert content from file %1: %2" ).
00249 arg( path ).arg( file.errorString() ) );
00250 }
00251
00252 } else if ( cmd.startsWith( "SYSTEM=" ) ) {
00253
00254 kdDebug() << "Command: SYSTEM=" << endl;
00255 QString q;
00256 int len = parseQuotes( "SYSTEM=", cmd, q );
00257 i += len;
00258 QString pipe_cmd = q;
00259 QString str = pipe( pipe_cmd, "" );
00260 body.append( str );
00261
00262 } else if ( cmd.startsWith( "PUT=" ) ) {
00263
00264 kdDebug() << "Command: PUT=" << endl;
00265 QString q;
00266 int len = parseQuotes( "PUT=", cmd, q );
00267 i += len;
00268 QString path = KShell::tildeExpand( q );
00269 QFileInfo finfo( path );
00270 if (finfo.isRelative() ) {
00271 path = KShell::homeDir( "" );
00272 path += '/';
00273 path += q;
00274 }
00275 QFile file( path );
00276 if ( file.open( IO_ReadOnly ) ) {
00277 QByteArray content = file.readAll();
00278 body.append( QString::fromLocal8Bit( content, content.size() ) );
00279 } else if ( mDebug ) {
00280 KMessageBox::error( 0,
00281 i18n( "Cannot insert content from file %1: %2").
00282 arg( path ).arg(file.errorString() ));
00283 }
00284
00285 } else if ( cmd.startsWith( "QUOTEPIPE=" ) ) {
00286
00287 kdDebug() << "Command: QUOTEPIPE=" << endl;
00288 QString q;
00289 int len = parseQuotes( "QUOTEPIPE=", cmd, q );
00290 i += len;
00291 QString pipe_cmd = q;
00292 if ( mOrigMsg && !mNoQuote ) {
00293 QString str = pipe( pipe_cmd, messageText( false ) );
00294 QString quote = mOrigMsg->asQuotedString( "", mQuoteString, str,
00295 mSmartQuote, mAllowDecryption );
00296 body.append( quote );
00297 }
00298
00299 } else if ( cmd.startsWith( "QUOTE" ) ) {
00300 kdDebug() << "Command: QUOTE" << endl;
00301 i += strlen( "QUOTE" );
00302 if ( mOrigMsg && !mNoQuote ) {
00303 QString quote = mOrigMsg->asQuotedString( "", mQuoteString, messageText( true ),
00304 mSmartQuote, mAllowDecryption );
00305 body.append( quote );
00306 }
00307
00308 } else if ( cmd.startsWith( "QHEADERS" ) ) {
00309 kdDebug() << "Command: QHEADERS" << endl;
00310 i += strlen( "QHEADERS" );
00311 if ( mOrigMsg && !mNoQuote ) {
00312 QString quote = mOrigMsg->asQuotedString( "", mQuoteString,
00313 mOrigMsg->headerAsSendableString(),
00314 mSmartQuote, false );
00315 body.append( quote );
00316 }
00317
00318 } else if ( cmd.startsWith( "HEADERS" ) ) {
00319 kdDebug() << "Command: HEADERS" << endl;
00320 i += strlen( "HEADERS" );
00321 if ( mOrigMsg && !mNoQuote ) {
00322 QString str = mOrigMsg->headerAsSendableString();
00323 body.append( str );
00324 }
00325
00326 } else if ( cmd.startsWith( "TEXTPIPE=" ) ) {
00327
00328 kdDebug() << "Command: TEXTPIPE=" << endl;
00329 QString q;
00330 int len = parseQuotes( "TEXTPIPE=", cmd, q );
00331 i += len;
00332 QString pipe_cmd = q;
00333 if ( mOrigMsg ) {
00334 QString str = pipe(pipe_cmd, messageText( false ) );
00335 body.append( str );
00336 }
00337
00338 } else if ( cmd.startsWith( "MSGPIPE=" ) ) {
00339
00340 kdDebug() << "Command: MSGPIPE=" << endl;
00341 QString q;
00342 int len = parseQuotes( "MSGPIPE=", cmd, q );
00343 i += len;
00344 QString pipe_cmd = q;
00345 if ( mOrigMsg ) {
00346 QString str = pipe(pipe_cmd, mOrigMsg->asString() );
00347 body.append( str );
00348 }
00349
00350 } else if ( cmd.startsWith( "BODYPIPE=" ) ) {
00351
00352 kdDebug() << "Command: BODYPIPE=" << endl;
00353 QString q;
00354 int len = parseQuotes( "BODYPIPE=", cmd, q );
00355 i += len;
00356 QString pipe_cmd = q;
00357 QString str = pipe( pipe_cmd, body );
00358 body.append( str );
00359
00360 } else if ( cmd.startsWith( "CLEARPIPE=" ) ) {
00361
00362
00363 kdDebug() << "Command: CLEARPIPE=" << endl;
00364 QString q;
00365 int len = parseQuotes( "CLEARPIPE=", cmd, q );
00366 i += len;
00367 QString pipe_cmd = q;
00368 QString str = pipe( pipe_cmd, body );
00369 body = str;
00370 mMsg->setCursorPos( 0 );
00371
00372 } else if ( cmd.startsWith( "TEXT" ) ) {
00373 kdDebug() << "Command: TEXT" << endl;
00374 i += strlen( "TEXT" );
00375 if ( mOrigMsg ) {
00376 QString quote = messageText( false );
00377 body.append( quote );
00378 }
00379
00380 } else if ( cmd.startsWith( "OTEXTSIZE" ) ) {
00381 kdDebug() << "Command: OTEXTSIZE" << endl;
00382 i += strlen( "OTEXTSIZE" );
00383 if ( mOrigMsg ) {
00384 QString str = QString( "%1" ).arg( mOrigMsg->body().length() );
00385 body.append( str );
00386 }
00387
00388 } else if ( cmd.startsWith( "OTEXT" ) ) {
00389 kdDebug() << "Command: OTEXT" << endl;
00390 i += strlen( "OTEXT" );
00391 if ( mOrigMsg ) {
00392 QString quote = messageText( false );
00393 body.append( quote );
00394 }
00395
00396 } else if ( cmd.startsWith( "CCADDR" ) ) {
00397 kdDebug() << "Command: CCADDR" << endl;
00398 i += strlen( "CCADDR" );
00399 QString str = mMsg->cc();
00400 body.append( str );
00401
00402 } else if ( cmd.startsWith( "CCNAME" ) ) {
00403 kdDebug() << "Command: CCNAME" << endl;
00404 i += strlen( "CCNAME" );
00405 QString str = mMsg->ccStrip();
00406 body.append( str );
00407
00408 } else if ( cmd.startsWith( "CCFNAME" ) ) {
00409 kdDebug() << "Command: CCFNAME" << endl;
00410 i += strlen( "CCFNAME" );
00411 QString str = mMsg->ccStrip();
00412 body.append( getFName( str ) );
00413
00414 } else if ( cmd.startsWith( "CCLNAME" ) ) {
00415 kdDebug() << "Command: CCLNAME" << endl;
00416 i += strlen( "CCLNAME" );
00417 QString str = mMsg->ccStrip();
00418 body.append( getLName( str ) );
00419
00420 } else if ( cmd.startsWith( "TOADDR" ) ) {
00421 kdDebug() << "Command: TOADDR" << endl;
00422 i += strlen( "TOADDR" );
00423 QString str = mMsg->to();
00424 body.append( str );
00425
00426 } else if ( cmd.startsWith( "TONAME" ) ) {
00427 kdDebug() << "Command: TONAME" << endl;
00428 i += strlen( "TONAME" );
00429 QString str = mMsg->toStrip();
00430 body.append( str );
00431
00432 } else if ( cmd.startsWith( "TOFNAME" ) ) {
00433 kdDebug() << "Command: TOFNAME" << endl;
00434 i += strlen( "TOFNAME" );
00435 QString str = mMsg->toStrip();
00436 body.append( getFName( str ) );
00437
00438 } else if ( cmd.startsWith( "TOLNAME" ) ) {
00439 kdDebug() << "Command: TOLNAME" << endl;
00440 i += strlen( "TOLNAME" );
00441 QString str = mMsg->toStrip();
00442 body.append( getLName( str ) );
00443
00444 } else if ( cmd.startsWith( "TOLIST" ) ) {
00445 kdDebug() << "Command: TOLIST" << endl;
00446 i += strlen( "TOLIST" );
00447 QString str = mMsg->to();
00448 body.append( str );
00449
00450 } else if ( cmd.startsWith( "FROMADDR" ) ) {
00451 kdDebug() << "Command: FROMADDR" << endl;
00452 i += strlen( "FROMADDR" );
00453 QString str = mMsg->from();
00454 body.append( str );
00455
00456 } else if ( cmd.startsWith( "FROMNAME" ) ) {
00457 kdDebug() << "Command: FROMNAME" << endl;
00458 i += strlen( "FROMNAME" );
00459 QString str = mMsg->fromStrip();
00460 body.append( str );
00461
00462 } else if ( cmd.startsWith( "FROMFNAME" ) ) {
00463 kdDebug() << "Command: FROMFNAME" << endl;
00464 i += strlen( "FROMFNAME" );
00465 QString str = mMsg->fromStrip();
00466 body.append( getFName( str ) );
00467
00468 } else if ( cmd.startsWith( "FROMLNAME" ) ) {
00469 kdDebug() << "Command: FROMLNAME" << endl;
00470 i += strlen( "FROMLNAME" );
00471 QString str = mMsg->fromStrip();
00472 body.append( getLName( str ) );
00473
00474 } else if ( cmd.startsWith( "FULLSUBJECT" ) ) {
00475 kdDebug() << "Command: FULLSUBJECT" << endl;
00476 i += strlen( "FULLSUBJECT" );
00477 QString str = mMsg->subject();
00478 body.append( str );
00479
00480 } else if ( cmd.startsWith( "FULLSUBJ" ) ) {
00481 kdDebug() << "Command: FULLSUBJ" << endl;
00482 i += strlen( "FULLSUBJ" );
00483 QString str = mMsg->subject();
00484 body.append( str );
00485
00486 } else if ( cmd.startsWith( "MSGID" ) ) {
00487 kdDebug() << "Command: MSGID" << endl;
00488 i += strlen( "MSGID" );
00489 QString str = mMsg->id();
00490 body.append( str );
00491
00492 } else if ( cmd.startsWith( "OHEADER=" ) ) {
00493
00494 kdDebug() << "Command: OHEADER=" << endl;
00495 QString q;
00496 int len = parseQuotes( "OHEADER=", cmd, q );
00497 i += len;
00498 if ( mOrigMsg ) {
00499 QString hdr = q;
00500 QString str = mOrigMsg->headerFields(hdr.local8Bit() ).join( ", " );
00501 body.append( str );
00502 }
00503
00504 } else if ( cmd.startsWith( "HEADER=" ) ) {
00505
00506 kdDebug() << "Command: HEADER=" << endl;
00507 QString q;
00508 int len = parseQuotes( "HEADER=", cmd, q );
00509 i += len;
00510 QString hdr = q;
00511 QString str = mMsg->headerFields(hdr.local8Bit() ).join( ", " );
00512 body.append( str );
00513
00514 } else if ( cmd.startsWith( "HEADER( " ) ) {
00515
00516 kdDebug() << "Command: HEADER( " << endl;
00517 QRegExp re = QRegExp( "^HEADER\\((.+)\\)" );
00518 re.setMinimal( true );
00519 int res = re.search( cmd );
00520 if ( res != 0 ) {
00521
00522 i += strlen( "HEADER( " );
00523 } else {
00524 i += re.matchedLength();
00525 QString hdr = re.cap( 1 );
00526 QString str = mMsg->headerFields( hdr.local8Bit() ).join( ", " );
00527 body.append( str );
00528 }
00529
00530 } else if ( cmd.startsWith( "OCCADDR" ) ) {
00531 kdDebug() << "Command: OCCADDR" << endl;
00532 i += strlen( "OCCADDR" );
00533 if ( mOrigMsg ) {
00534 QString str = mOrigMsg->cc();
00535 body.append( str );
00536 }
00537
00538 } else if ( cmd.startsWith( "OCCNAME" ) ) {
00539 kdDebug() << "Command: OCCNAME" << endl;
00540 i += strlen( "OCCNAME" );
00541 if ( mOrigMsg ) {
00542 QString str = mOrigMsg->ccStrip();
00543 body.append( str );
00544 }
00545
00546 } else if ( cmd.startsWith( "OCCFNAME" ) ) {
00547 kdDebug() << "Command: OCCFNAME" << endl;
00548 i += strlen( "OCCFNAME" );
00549 if ( mOrigMsg ) {
00550 QString str = mOrigMsg->ccStrip();
00551 body.append( getFName( str ) );
00552 }
00553
00554 } else if ( cmd.startsWith( "OCCLNAME" ) ) {
00555 kdDebug() << "Command: OCCLNAME" << endl;
00556 i += strlen( "OCCLNAME" );
00557 if ( mOrigMsg ) {
00558 QString str = mOrigMsg->ccStrip();
00559 body.append( getLName( str ) );
00560 }
00561
00562 } else if ( cmd.startsWith( "OTOADDR" ) ) {
00563 kdDebug() << "Command: OTOADDR" << endl;
00564 i += strlen( "OTOADDR" );
00565 if ( mOrigMsg ) {
00566 QString str = mOrigMsg->to();
00567 body.append( str );
00568 }
00569
00570 } else if ( cmd.startsWith( "OTONAME" ) ) {
00571 kdDebug() << "Command: OTONAME" << endl;
00572 i += strlen( "OTONAME" );
00573 if ( mOrigMsg ) {
00574 QString str = mOrigMsg->toStrip();
00575 body.append( str );
00576 }
00577
00578 } else if ( cmd.startsWith( "OTOFNAME" ) ) {
00579 kdDebug() << "Command: OTOFNAME" << endl;
00580 i += strlen( "OTOFNAME" );
00581 if ( mOrigMsg ) {
00582 QString str = mOrigMsg->toStrip();
00583 body.append( getFName( str ) );
00584 }
00585
00586 } else if ( cmd.startsWith( "OTOLNAME" ) ) {
00587 kdDebug() << "Command: OTOLNAME" << endl;
00588 i += strlen( "OTOLNAME" );
00589 if ( mOrigMsg ) {
00590 QString str = mOrigMsg->toStrip();
00591 body.append( getLName( str ) );
00592 }
00593
00594 } else if ( cmd.startsWith( "OTOLIST" ) ) {
00595 kdDebug() << "Command: OTOLIST" << endl;
00596 i += strlen( "OTOLIST" );
00597 if ( mOrigMsg ) {
00598 QString str = mOrigMsg->to();
00599 body.append( str );
00600 }
00601
00602 } else if ( cmd.startsWith( "OTO" ) ) {
00603 kdDebug() << "Command: OTO" << endl;
00604 i += strlen( "OTO" );
00605 if ( mOrigMsg ) {
00606 QString str = mOrigMsg->to();
00607 body.append( str );
00608 }
00609
00610 } else if ( cmd.startsWith( "OFROMADDR" ) ) {
00611 kdDebug() << "Command: OFROMADDR" << endl;
00612 i += strlen( "OFROMADDR" );
00613 if ( mOrigMsg ) {
00614 QString str = mOrigMsg->from();
00615 body.append( str );
00616 }
00617
00618 } else if ( cmd.startsWith( "OFROMNAME" ) ) {
00619 kdDebug() << "Command: OFROMNAME" << endl;
00620 i += strlen( "OFROMNAME" );
00621 if ( mOrigMsg ) {
00622 QString str = mOrigMsg->fromStrip();
00623 body.append( str );
00624 }
00625
00626 } else if ( cmd.startsWith( "OFROMFNAME" ) ) {
00627 kdDebug() << "Command: OFROMFNAME" << endl;
00628 i += strlen( "OFROMFNAME" );
00629 if ( mOrigMsg ) {
00630 QString str = mOrigMsg->fromStrip();
00631 body.append( getFName( str ) );
00632 }
00633
00634 } else if ( cmd.startsWith( "OFROMLNAME" ) ) {
00635 kdDebug() << "Command: OFROMLNAME" << endl;
00636 i += strlen( "OFROMLNAME" );
00637 if ( mOrigMsg ) {
00638 QString str = mOrigMsg->fromStrip();
00639 body.append( getLName( str ) );
00640 }
00641
00642 } else if ( cmd.startsWith( "OFULLSUBJECT" ) ) {
00643 kdDebug() << "Command: OFULLSUBJECT" << endl;
00644 i += strlen( "OFULLSUBJECT" );
00645 if ( mOrigMsg ) {
00646 QString str = mOrigMsg->subject();
00647 body.append( str );
00648 }
00649
00650 } else if ( cmd.startsWith( "OFULLSUBJ" ) ) {
00651 kdDebug() << "Command: OFULLSUBJ" << endl;
00652 i += strlen( "OFULLSUBJ" );
00653 if ( mOrigMsg ) {
00654 QString str = mOrigMsg->subject();
00655 body.append( str );
00656 }
00657
00658 } else if ( cmd.startsWith( "OMSGID" ) ) {
00659 kdDebug() << "Command: OMSGID" << endl;
00660 i += strlen( "OMSGID" );
00661 if ( mOrigMsg ) {
00662 QString str = mOrigMsg->id();
00663 body.append( str );
00664 }
00665
00666 } else if ( cmd.startsWith( "DATEEN" ) ) {
00667 kdDebug() << "Command: DATEEN" << endl;
00668 i += strlen( "DATEEN" );
00669 QDateTime date = QDateTime::currentDateTime();
00670 KLocale locale( "C" );
00671 QString str = locale.formatDate( date.date(), false );
00672 body.append( str );
00673
00674 } else if ( cmd.startsWith( "DATESHORT" ) ) {
00675 kdDebug() << "Command: DATESHORT" << endl;
00676 i += strlen( "DATESHORT" );
00677 QDateTime date = QDateTime::currentDateTime();
00678 QString str = KGlobal::locale()->formatDate( date.date(), true );
00679 body.append( str );
00680
00681 } else if ( cmd.startsWith( "DATE" ) ) {
00682 kdDebug() << "Command: DATE" << endl;
00683 i += strlen( "DATE" );
00684 QDateTime date = QDateTime::currentDateTime();
00685 QString str = KGlobal::locale()->formatDate( date.date(), false );
00686 body.append( str );
00687
00688 } else if ( cmd.startsWith( "DOW" ) ) {
00689 kdDebug() << "Command: DOW" << endl;
00690 i += strlen( "DOW" );
00691 QDateTime date = QDateTime::currentDateTime();
00692 QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false );
00693 body.append( str );
00694
00695 } else if ( cmd.startsWith( "TIMELONGEN" ) ) {
00696 kdDebug() << "Command: TIMELONGEN" << endl;
00697 i += strlen( "TIMELONGEN" );
00698 QDateTime date = QDateTime::currentDateTime();
00699 KLocale locale( "C");
00700 QString str = locale.formatTime( date.time(), true );
00701 body.append( str );
00702
00703 } else if ( cmd.startsWith( "TIMELONG" ) ) {
00704 kdDebug() << "Command: TIMELONG" << endl;
00705 i += strlen( "TIMELONG" );
00706 QDateTime date = QDateTime::currentDateTime();
00707 QString str = KGlobal::locale()->formatTime( date.time(), true );
00708 body.append( str );
00709
00710 } else if ( cmd.startsWith( "TIME" ) ) {
00711 kdDebug() << "Command: TIME" << endl;
00712 i += strlen( "TIME" );
00713 QDateTime date = QDateTime::currentDateTime();
00714 QString str = KGlobal::locale()->formatTime( date.time(), false );
00715 body.append( str );
00716
00717 } else if ( cmd.startsWith( "ODATEEN" ) ) {
00718 kdDebug() << "Command: ODATEEN" << endl;
00719 i += strlen( "ODATEEN" );
00720 if ( mOrigMsg ) {
00721 QDateTime date;
00722 date.setTime_t( mOrigMsg->date() );
00723 KLocale locale( "C");
00724 QString str = locale.formatDate( date.date(), false );
00725 body.append( str );
00726 }
00727
00728 } else if ( cmd.startsWith( "ODATESHORT") ) {
00729 kdDebug() << "Command: ODATESHORT" << endl;
00730 i += strlen( "ODATESHORT");
00731 if ( mOrigMsg ) {
00732 QDateTime date;
00733 date.setTime_t( mOrigMsg->date() );
00734 QString str = KGlobal::locale()->formatDate( date.date(), true );
00735 body.append( str );
00736 }
00737
00738 } else if ( cmd.startsWith( "ODATE") ) {
00739 kdDebug() << "Command: ODATE" << endl;
00740 i += strlen( "ODATE");
00741 if ( mOrigMsg ) {
00742 QDateTime date;
00743 date.setTime_t( mOrigMsg->date() );
00744 QString str = KGlobal::locale()->formatDate( date.date(), false );
00745 body.append( str );
00746 }
00747
00748 } else if ( cmd.startsWith( "ODOW") ) {
00749 kdDebug() << "Command: ODOW" << endl;
00750 i += strlen( "ODOW");
00751 if ( mOrigMsg ) {
00752 QDateTime date;
00753 date.setTime_t( mOrigMsg->date() );
00754 QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false );
00755 body.append( str );
00756 }
00757
00758 } else if ( cmd.startsWith( "OTIMELONGEN") ) {
00759 kdDebug() << "Command: OTIMELONGEN" << endl;
00760 i += strlen( "OTIMELONGEN");
00761 if ( mOrigMsg ) {
00762 QDateTime date;
00763 date.setTime_t( mOrigMsg->date() );
00764 KLocale locale( "C");
00765 QString str = locale.formatTime( date.time(), true );
00766 body.append( str );
00767 }
00768
00769 } else if ( cmd.startsWith( "OTIMELONG") ) {
00770 kdDebug() << "Command: OTIMELONG" << endl;
00771 i += strlen( "OTIMELONG");
00772 if ( mOrigMsg ) {
00773 QDateTime date;
00774 date.setTime_t( mOrigMsg->date() );
00775 QString str = KGlobal::locale()->formatTime( date.time(), true );
00776 body.append( str );
00777 }
00778
00779 } else if ( cmd.startsWith( "OTIME") ) {
00780 kdDebug() << "Command: OTIME" << endl;
00781 i += strlen( "OTIME");
00782 if ( mOrigMsg ) {
00783 QDateTime date;
00784 date.setTime_t( mOrigMsg->date() );
00785 QString str = KGlobal::locale()->formatTime( date.time(), false );
00786 body.append( str );
00787 }
00788
00789 } else if ( cmd.startsWith( "BLANK" ) ) {
00790
00791 kdDebug() << "Command: BLANK" << endl;
00792 i += strlen( "BLANK" );
00793
00794 } else if ( cmd.startsWith( "NOP" ) ) {
00795
00796 kdDebug() << "Command: NOP" << endl;
00797 i += strlen( "NOP" );
00798
00799 } else if ( cmd.startsWith( "CLEAR" ) ) {
00800
00801 kdDebug() << "Command: CLEAR" << endl;
00802 i += strlen( "CLEAR" );
00803 body = "";
00804 mMsg->setCursorPos( 0 );
00805
00806 } else if ( cmd.startsWith( "DEBUGOFF" ) ) {
00807
00808 kdDebug() << "Command: DEBUGOFF" << endl;
00809 i += strlen( "DEBUGOFF" );
00810 mDebug = false;
00811
00812 } else if ( cmd.startsWith( "DEBUG" ) ) {
00813
00814 kdDebug() << "Command: DEBUG" << endl;
00815 i += strlen( "DEBUG" );
00816 mDebug = true;
00817
00818 } else if ( cmd.startsWith( "CURSOR" ) ) {
00819
00820 kdDebug() << "Command: CURSOR" << endl;
00821 i += strlen( "CURSOR" );
00822 mMsg->setCursorPos( body.length() );
00823
00824 } else {
00825
00826 body.append( c );
00827 }
00828
00829 } else if ( dnl && ( c == '\n' || c == '\r') ) {
00830
00831 if ( ( c == '\n' && tmpl[i + 1] == '\r' ) ||
00832 ( c == '\r' && tmpl[i + 1] == '\n' ) ) {
00833
00834 i += 1;
00835 }
00836 dnl = false;
00837 } else {
00838 body.append( c );
00839 }
00840 }
00841
00842 addProcessedBodyToMessage( body );
00843 }
00844
00845 QString TemplateParser::messageText( bool allowSelectionOnly )
00846 {
00847 if ( !mSelection.isEmpty() && allowSelectionOnly )
00848 return mSelection;
00849
00850
00851 partNode *root = parsedObjectTree();
00852 return mOrigMsg->asPlainTextFromObjectTree( root, true, mAllowDecryption );
00853 }
00854
00855 partNode* TemplateParser::parsedObjectTree()
00856 {
00857 if ( mOrigRoot )
00858 return mOrigRoot;
00859
00860 mOrigRoot = partNode::fromMessage( mOrigMsg );
00861 KMail::ObjectTreeParser otp;
00862 otp.parseObjectTree( mOrigRoot );
00863 return mOrigRoot;
00864 }
00865
00866 void TemplateParser::addProcessedBodyToMessage( const QString &body )
00867 {
00868 if ( mAppend ) {
00869
00870
00871 QCString msg_body = mMsg->body();
00872 msg_body.append( body.utf8() );
00873 mMsg->setBody( msg_body );
00874 }
00875 else {
00876
00877
00878 partNode *root = parsedObjectTree();
00879 KMail::AttachmentCollector ac;
00880 ac.collectAttachmentsFrom( root );
00881
00882
00883
00884 mMsg->deleteBodyParts();
00885
00886
00887 if ( mMode == Forward ) {
00888 if ( !mTo.isEmpty() ) {
00889 mMsg->setTo( mMsg->to() + ',' + mTo );
00890 }
00891 if ( !mCC.isEmpty() )
00892 mMsg->setCc( mMsg->cc() + ',' + mCC );
00893 }
00894
00895
00896
00897 if ( ac.attachments().empty() || mMode != Forward ) {
00898 mMsg->headers().ContentType().FromString( DwString() );
00899 mMsg->headers().ContentType().Parse();
00900 mMsg->headers().ContentType().SetType( DwMime::kTypeText );
00901 mMsg->headers().ContentType().SetSubtype( DwMime::kSubtypePlain );
00902 mMsg->headers().Assemble();
00903 mMsg->setBodyFromUnicode( body );
00904 mMsg->assembleIfNeeded();
00905 }
00906
00907
00908
00909 else
00910 {
00911 mMsg->headers().ContentType().SetType( DwMime::kTypeMultipart );
00912 mMsg->headers().ContentType().SetSubtype( DwMime::kSubtypeMixed );
00913 mMsg->headers().ContentType().CreateBoundary( 0 );
00914
00915 KMMessagePart textPart;
00916 textPart.setBodyFromUnicode( body );
00917 mMsg->addDwBodyPart( mMsg->createDWBodyPart( &textPart ) );
00918 mMsg->assembleIfNeeded();
00919
00920 for ( std::vector<partNode*>::const_iterator it = ac.attachments().begin();
00921 it != ac.attachments().end(); ++it ) {
00922
00923
00924
00925
00926
00927 ( *it )->dwPart()->SetNext( 0 );
00928
00929 mMsg->addDwBodyPart( static_cast<DwBodyPart*>( ( *it )->dwPart()->Clone() ) );
00930 mMsg->assembleIfNeeded();
00931 }
00932 }
00933 }
00934 }
00935
00936 QString TemplateParser::findCustomTemplate( const QString &tmplName )
00937 {
00938 CTemplates t( tmplName );
00939 mTo = t.to();
00940 mCC = t.cC();
00941 QString content = t.content();
00942 if ( !content.isEmpty() ) {
00943 return content;
00944 } else {
00945 return findTemplate();
00946 }
00947 }
00948
00949 QString TemplateParser::findTemplate()
00950 {
00951
00952 if ( !GlobalSettings::self()->phrasesConverted() ) {
00953 TemplatesConfiguration::importFromPhrases();
00954 }
00955
00956
00957
00958 QString tmpl;
00959
00960 if ( !mFolder ) {
00961 mFolder = mMsg->parent();
00962 if ( !mFolder ) {
00963 if ( mOrigMsg ) {
00964 mFolder = mOrigMsg->parent();
00965 }
00966 if ( !mFolder ) {
00967 kdDebug(5006) << "Oops! No folder for message" << endl;
00968 }
00969 }
00970 }
00971 kdDebug(5006) << "Folder found: " << mFolder << endl;
00972
00973 if ( mFolder )
00974 {
00975 QString fid = mFolder->idString();
00976 Templates fconf( fid );
00977 if ( fconf.useCustomTemplates() ) {
00978 switch( mMode ) {
00979 case NewMessage:
00980 tmpl = fconf.templateNewMessage();
00981 break;
00982 case Reply:
00983 tmpl = fconf.templateReply();
00984 break;
00985 case ReplyAll:
00986 tmpl = fconf.templateReplyAll();
00987 break;
00988 case Forward:
00989 tmpl = fconf.templateForward();
00990 break;
00991 default:
00992 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
00993 return "";
00994 }
00995 mQuoteString = fconf.quoteString();
00996 if ( !tmpl.isEmpty() ) {
00997 return tmpl;
00998 }
00999 }
01000 }
01001
01002 if ( !mIdentity ) {
01003 mIdentity = mMsg->identityUoid();
01004 if ( !mIdentity && mOrigMsg ) {
01005 mIdentity = mOrigMsg->identityUoid();
01006 }
01007 mIdentity = kmkernel->identityManager()->identityForUoidOrDefault( mIdentity ).uoid();
01008 if ( !mIdentity ) {
01009 kdDebug(5006) << "Oops! No identity for message" << endl;
01010 }
01011 }
01012 kdDebug(5006) << "Identity found: " << mIdentity << endl;
01013
01014 QString iid;
01015 if ( mIdentity ) {
01016 iid = QString("IDENTITY_%1").arg( mIdentity );
01017 }
01018 else {
01019 iid = "IDENTITY_NO_IDENTITY";
01020 }
01021
01022 Templates iconf( iid );
01023 if ( iconf.useCustomTemplates() ) {
01024 switch( mMode ) {
01025 case NewMessage:
01026 tmpl = iconf.templateNewMessage();
01027 break;
01028 case Reply:
01029 tmpl = iconf.templateReply();
01030 break;
01031 case ReplyAll:
01032 tmpl = iconf.templateReplyAll();
01033 break;
01034 case Forward:
01035 tmpl = iconf.templateForward();
01036 break;
01037 default:
01038 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
01039 return "";
01040 }
01041 mQuoteString = iconf.quoteString();
01042 if ( !tmpl.isEmpty() ) {
01043 return tmpl;
01044 }
01045 }
01046
01047 switch( mMode ) {
01048 case NewMessage:
01049 tmpl = GlobalSettings::self()->templateNewMessage();
01050 break;
01051 case Reply:
01052 tmpl = GlobalSettings::self()->templateReply();
01053 break;
01054 case ReplyAll:
01055 tmpl = GlobalSettings::self()->templateReplyAll();
01056 break;
01057 case Forward:
01058 tmpl = GlobalSettings::self()->templateForward();
01059 break;
01060 default:
01061 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
01062 return "";
01063 }
01064
01065 mQuoteString = GlobalSettings::self()->quoteString();
01066 return tmpl;
01067 }
01068
01069 QString TemplateParser::pipe( const QString &cmd, const QString &buf )
01070 {
01071 mPipeOut = "";
01072 mPipeErr = "";
01073 mPipeRc = 0;
01074
01075 KProcess proc;
01076 QCString data = buf.local8Bit();
01077
01078
01079
01080 proc << KShell::splitArgs( cmd, KShell::TildeExpand );
01081 proc.setUseShell( true );
01082 connect( &proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
01083 this, SLOT( onReceivedStdout( KProcess *, char *, int ) ) );
01084 connect( &proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
01085 this, SLOT( onReceivedStderr( KProcess *, char *, int ) ) );
01086 connect( &proc, SIGNAL( wroteStdin( KProcess * ) ),
01087 this, SLOT( onWroteStdin( KProcess * ) ) );
01088
01089 if ( proc.start( KProcess::NotifyOnExit, KProcess::All ) ) {
01090
01091 bool pipe_filled = proc.writeStdin( data, data.length() );
01092 if ( pipe_filled ) {
01093 proc.closeStdin();
01094
01095 bool exited = proc.wait( PipeTimeout );
01096 if ( exited ) {
01097
01098 if ( proc.normalExit() ) {
01099
01100 mPipeRc = proc.exitStatus();
01101 if ( mPipeRc != 0 && mDebug ) {
01102 if ( mPipeErr.isEmpty() ) {
01103 KMessageBox::error( 0,
01104 i18n( "Pipe command exit with status %1: %2").
01105 arg( mPipeRc ).arg( cmd ) );
01106 } else {
01107 KMessageBox::detailedError( 0,
01108 i18n( "Pipe command exit with status %1: %2" ).
01109 arg( mPipeRc ).arg( cmd ), mPipeErr );
01110 }
01111 }
01112
01113 } else {
01114
01115 mPipeRc = -( proc.exitSignal() );
01116 if ( mPipeRc != 0 && mDebug ) {
01117 if ( mPipeErr.isEmpty() ) {
01118 KMessageBox::error( 0,
01119 i18n( "Pipe command killed by signal %1: %2" ).
01120 arg( -(mPipeRc) ).arg( cmd ) );
01121 } else {
01122 KMessageBox::detailedError( 0,
01123 i18n( "Pipe command killed by signal %1: %2" ).
01124 arg( -(mPipeRc) ).arg( cmd ), mPipeErr );
01125 }
01126 }
01127 }
01128
01129 } else {
01130
01131 proc.kill();
01132 proc.detach();
01133 if ( mDebug ) {
01134 KMessageBox::error( 0,
01135 i18n( "Pipe command did not finish within %1 seconds: %2" ).
01136 arg( PipeTimeout ).arg( cmd ) );
01137 }
01138 }
01139
01140 } else {
01141
01142 proc.kill();
01143 proc.detach();
01144 if ( mDebug ) {
01145 if ( mPipeErr.isEmpty() ) {
01146 KMessageBox::error( 0,
01147 i18n( "Cannot write to process stdin: %1" ).arg( cmd ) );
01148 } else {
01149 KMessageBox::detailedError( 0,
01150 i18n( "Cannot write to process stdin: %1" ).
01151 arg( cmd ), mPipeErr );
01152 }
01153 }
01154 }
01155
01156 } else if ( mDebug ) {
01157 KMessageBox::error( 0,
01158 i18n( "Cannot start pipe command from template: %1" ).
01159 arg( cmd ) );
01160 }
01161
01162 return mPipeOut;
01163 }
01164
01165 void TemplateParser::onProcessExited( KProcess *proc )
01166 {
01167 Q_UNUSED( proc );
01168
01169 }
01170
01171 void TemplateParser::onReceivedStdout( KProcess *proc, char *buffer, int buflen )
01172 {
01173 Q_UNUSED( proc );
01174 mPipeOut += QString::fromLocal8Bit( buffer, buflen );
01175 }
01176
01177 void TemplateParser::onReceivedStderr( KProcess *proc, char *buffer, int buflen )
01178 {
01179 Q_UNUSED( proc );
01180 mPipeErr += QString::fromLocal8Bit( buffer, buflen );
01181 }
01182
01183 void TemplateParser::onWroteStdin( KProcess *proc )
01184 {
01185 proc->closeStdin();
01186 }
01187
01188 #include "templateparser.moc"