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( "OADDRESSEESADDR" ) ) {
00397 kdDebug() << "Command: OADDRESSEESADDR";
00398 i += strlen( "OADDRESSEESADDR" );
00399 const QString to = mOrigMsg->to();
00400 const QString cc = mOrigMsg->cc();
00401 if ( !to.isEmpty() )
00402 body.append( i18n( "To:" ) + ' ' + to );
00403 if ( !to.isEmpty() && !cc.isEmpty() )
00404 body.append( '\n' );
00405 if ( !cc.isEmpty() )
00406 body.append( i18n( "CC:" ) + ' ' + cc );
00407
00408 } else if ( cmd.startsWith( "CCADDR" ) ) {
00409 kdDebug() << "Command: CCADDR" << endl;
00410 i += strlen( "CCADDR" );
00411 QString str = mMsg->cc();
00412 body.append( str );
00413
00414 } else if ( cmd.startsWith( "CCNAME" ) ) {
00415 kdDebug() << "Command: CCNAME" << endl;
00416 i += strlen( "CCNAME" );
00417 QString str = mMsg->ccStrip();
00418 body.append( str );
00419
00420 } else if ( cmd.startsWith( "CCFNAME" ) ) {
00421 kdDebug() << "Command: CCFNAME" << endl;
00422 i += strlen( "CCFNAME" );
00423 QString str = mMsg->ccStrip();
00424 body.append( getFName( str ) );
00425
00426 } else if ( cmd.startsWith( "CCLNAME" ) ) {
00427 kdDebug() << "Command: CCLNAME" << endl;
00428 i += strlen( "CCLNAME" );
00429 QString str = mMsg->ccStrip();
00430 body.append( getLName( str ) );
00431
00432 } else if ( cmd.startsWith( "TOADDR" ) ) {
00433 kdDebug() << "Command: TOADDR" << endl;
00434 i += strlen( "TOADDR" );
00435 QString str = mMsg->to();
00436 body.append( str );
00437
00438 } else if ( cmd.startsWith( "TONAME" ) ) {
00439 kdDebug() << "Command: TONAME" << endl;
00440 i += strlen( "TONAME" );
00441 QString str = mMsg->toStrip();
00442 body.append( str );
00443
00444 } else if ( cmd.startsWith( "TOFNAME" ) ) {
00445 kdDebug() << "Command: TOFNAME" << endl;
00446 i += strlen( "TOFNAME" );
00447 QString str = mMsg->toStrip();
00448 body.append( getFName( str ) );
00449
00450 } else if ( cmd.startsWith( "TOLNAME" ) ) {
00451 kdDebug() << "Command: TOLNAME" << endl;
00452 i += strlen( "TOLNAME" );
00453 QString str = mMsg->toStrip();
00454 body.append( getLName( str ) );
00455
00456 } else if ( cmd.startsWith( "TOLIST" ) ) {
00457 kdDebug() << "Command: TOLIST" << endl;
00458 i += strlen( "TOLIST" );
00459 QString str = mMsg->to();
00460 body.append( str );
00461
00462 } else if ( cmd.startsWith( "FROMADDR" ) ) {
00463 kdDebug() << "Command: FROMADDR" << endl;
00464 i += strlen( "FROMADDR" );
00465 QString str = mMsg->from();
00466 body.append( str );
00467
00468 } else if ( cmd.startsWith( "FROMNAME" ) ) {
00469 kdDebug() << "Command: FROMNAME" << endl;
00470 i += strlen( "FROMNAME" );
00471 QString str = mMsg->fromStrip();
00472 body.append( str );
00473
00474 } else if ( cmd.startsWith( "FROMFNAME" ) ) {
00475 kdDebug() << "Command: FROMFNAME" << endl;
00476 i += strlen( "FROMFNAME" );
00477 QString str = mMsg->fromStrip();
00478 body.append( getFName( str ) );
00479
00480 } else if ( cmd.startsWith( "FROMLNAME" ) ) {
00481 kdDebug() << "Command: FROMLNAME" << endl;
00482 i += strlen( "FROMLNAME" );
00483 QString str = mMsg->fromStrip();
00484 body.append( getLName( str ) );
00485
00486 } else if ( cmd.startsWith( "FULLSUBJECT" ) ) {
00487 kdDebug() << "Command: FULLSUBJECT" << endl;
00488 i += strlen( "FULLSUBJECT" );
00489 QString str = mMsg->subject();
00490 body.append( str );
00491
00492 } else if ( cmd.startsWith( "FULLSUBJ" ) ) {
00493 kdDebug() << "Command: FULLSUBJ" << endl;
00494 i += strlen( "FULLSUBJ" );
00495 QString str = mMsg->subject();
00496 body.append( str );
00497
00498 } else if ( cmd.startsWith( "MSGID" ) ) {
00499 kdDebug() << "Command: MSGID" << endl;
00500 i += strlen( "MSGID" );
00501 QString str = mMsg->id();
00502 body.append( str );
00503
00504 } else if ( cmd.startsWith( "OHEADER=" ) ) {
00505
00506 kdDebug() << "Command: OHEADER=" << endl;
00507 QString q;
00508 int len = parseQuotes( "OHEADER=", cmd, q );
00509 i += len;
00510 if ( mOrigMsg ) {
00511 QString hdr = q;
00512 QString str = mOrigMsg->headerFields(hdr.local8Bit() ).join( ", " );
00513 body.append( str );
00514 }
00515
00516 } else if ( cmd.startsWith( "HEADER=" ) ) {
00517
00518 kdDebug() << "Command: HEADER=" << endl;
00519 QString q;
00520 int len = parseQuotes( "HEADER=", cmd, q );
00521 i += len;
00522 QString hdr = q;
00523 QString str = mMsg->headerFields(hdr.local8Bit() ).join( ", " );
00524 body.append( str );
00525
00526 } else if ( cmd.startsWith( "HEADER( " ) ) {
00527
00528 kdDebug() << "Command: HEADER( " << endl;
00529 QRegExp re = QRegExp( "^HEADER\\((.+)\\)" );
00530 re.setMinimal( true );
00531 int res = re.search( cmd );
00532 if ( res != 0 ) {
00533
00534 i += strlen( "HEADER( " );
00535 } else {
00536 i += re.matchedLength();
00537 QString hdr = re.cap( 1 );
00538 QString str = mMsg->headerFields( hdr.local8Bit() ).join( ", " );
00539 body.append( str );
00540 }
00541
00542 } else if ( cmd.startsWith( "OCCADDR" ) ) {
00543 kdDebug() << "Command: OCCADDR" << endl;
00544 i += strlen( "OCCADDR" );
00545 if ( mOrigMsg ) {
00546 QString str = mOrigMsg->cc();
00547 body.append( str );
00548 }
00549
00550 } else if ( cmd.startsWith( "OCCNAME" ) ) {
00551 kdDebug() << "Command: OCCNAME" << endl;
00552 i += strlen( "OCCNAME" );
00553 if ( mOrigMsg ) {
00554 QString str = mOrigMsg->ccStrip();
00555 body.append( str );
00556 }
00557
00558 } else if ( cmd.startsWith( "OCCFNAME" ) ) {
00559 kdDebug() << "Command: OCCFNAME" << endl;
00560 i += strlen( "OCCFNAME" );
00561 if ( mOrigMsg ) {
00562 QString str = mOrigMsg->ccStrip();
00563 body.append( getFName( str ) );
00564 }
00565
00566 } else if ( cmd.startsWith( "OCCLNAME" ) ) {
00567 kdDebug() << "Command: OCCLNAME" << endl;
00568 i += strlen( "OCCLNAME" );
00569 if ( mOrigMsg ) {
00570 QString str = mOrigMsg->ccStrip();
00571 body.append( getLName( str ) );
00572 }
00573
00574 } else if ( cmd.startsWith( "OTOADDR" ) ) {
00575 kdDebug() << "Command: OTOADDR" << endl;
00576 i += strlen( "OTOADDR" );
00577 if ( mOrigMsg ) {
00578 QString str = mOrigMsg->to();
00579 body.append( str );
00580 }
00581
00582 } else if ( cmd.startsWith( "OTONAME" ) ) {
00583 kdDebug() << "Command: OTONAME" << endl;
00584 i += strlen( "OTONAME" );
00585 if ( mOrigMsg ) {
00586 QString str = mOrigMsg->toStrip();
00587 body.append( str );
00588 }
00589
00590 } else if ( cmd.startsWith( "OTOFNAME" ) ) {
00591 kdDebug() << "Command: OTOFNAME" << endl;
00592 i += strlen( "OTOFNAME" );
00593 if ( mOrigMsg ) {
00594 QString str = mOrigMsg->toStrip();
00595 body.append( getFName( str ) );
00596 }
00597
00598 } else if ( cmd.startsWith( "OTOLNAME" ) ) {
00599 kdDebug() << "Command: OTOLNAME" << endl;
00600 i += strlen( "OTOLNAME" );
00601 if ( mOrigMsg ) {
00602 QString str = mOrigMsg->toStrip();
00603 body.append( getLName( str ) );
00604 }
00605
00606 } else if ( cmd.startsWith( "OTOLIST" ) ) {
00607 kdDebug() << "Command: OTOLIST" << endl;
00608 i += strlen( "OTOLIST" );
00609 if ( mOrigMsg ) {
00610 QString str = mOrigMsg->to();
00611 body.append( str );
00612 }
00613
00614 } else if ( cmd.startsWith( "OTO" ) ) {
00615 kdDebug() << "Command: OTO" << endl;
00616 i += strlen( "OTO" );
00617 if ( mOrigMsg ) {
00618 QString str = mOrigMsg->to();
00619 body.append( str );
00620 }
00621
00622 } else if ( cmd.startsWith( "OFROMADDR" ) ) {
00623 kdDebug() << "Command: OFROMADDR" << endl;
00624 i += strlen( "OFROMADDR" );
00625 if ( mOrigMsg ) {
00626 QString str = mOrigMsg->from();
00627 body.append( str );
00628 }
00629
00630 } else if ( cmd.startsWith( "OFROMNAME" ) ) {
00631 kdDebug() << "Command: OFROMNAME" << endl;
00632 i += strlen( "OFROMNAME" );
00633 if ( mOrigMsg ) {
00634 QString str = mOrigMsg->fromStrip();
00635 body.append( str );
00636 }
00637
00638 } else if ( cmd.startsWith( "OFROMFNAME" ) ) {
00639 kdDebug() << "Command: OFROMFNAME" << endl;
00640 i += strlen( "OFROMFNAME" );
00641 if ( mOrigMsg ) {
00642 QString str = mOrigMsg->fromStrip();
00643 body.append( getFName( str ) );
00644 }
00645
00646 } else if ( cmd.startsWith( "OFROMLNAME" ) ) {
00647 kdDebug() << "Command: OFROMLNAME" << endl;
00648 i += strlen( "OFROMLNAME" );
00649 if ( mOrigMsg ) {
00650 QString str = mOrigMsg->fromStrip();
00651 body.append( getLName( str ) );
00652 }
00653
00654 } else if ( cmd.startsWith( "OFULLSUBJECT" ) ) {
00655 kdDebug() << "Command: OFULLSUBJECT" << endl;
00656 i += strlen( "OFULLSUBJECT" );
00657 if ( mOrigMsg ) {
00658 QString str = mOrigMsg->subject();
00659 body.append( str );
00660 }
00661
00662 } else if ( cmd.startsWith( "OFULLSUBJ" ) ) {
00663 kdDebug() << "Command: OFULLSUBJ" << endl;
00664 i += strlen( "OFULLSUBJ" );
00665 if ( mOrigMsg ) {
00666 QString str = mOrigMsg->subject();
00667 body.append( str );
00668 }
00669
00670 } else if ( cmd.startsWith( "OMSGID" ) ) {
00671 kdDebug() << "Command: OMSGID" << endl;
00672 i += strlen( "OMSGID" );
00673 if ( mOrigMsg ) {
00674 QString str = mOrigMsg->id();
00675 body.append( str );
00676 }
00677
00678 } else if ( cmd.startsWith( "DATEEN" ) ) {
00679 kdDebug() << "Command: DATEEN" << endl;
00680 i += strlen( "DATEEN" );
00681 QDateTime date = QDateTime::currentDateTime();
00682 KLocale locale( "C" );
00683 QString str = locale.formatDate( date.date(), false );
00684 body.append( str );
00685
00686 } else if ( cmd.startsWith( "DATESHORT" ) ) {
00687 kdDebug() << "Command: DATESHORT" << endl;
00688 i += strlen( "DATESHORT" );
00689 QDateTime date = QDateTime::currentDateTime();
00690 QString str = KGlobal::locale()->formatDate( date.date(), true );
00691 body.append( str );
00692
00693 } else if ( cmd.startsWith( "DATE" ) ) {
00694 kdDebug() << "Command: DATE" << endl;
00695 i += strlen( "DATE" );
00696 QDateTime date = QDateTime::currentDateTime();
00697 QString str = KGlobal::locale()->formatDate( date.date(), false );
00698 body.append( str );
00699
00700 } else if ( cmd.startsWith( "DOW" ) ) {
00701 kdDebug() << "Command: DOW" << endl;
00702 i += strlen( "DOW" );
00703 QDateTime date = QDateTime::currentDateTime();
00704 QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false );
00705 body.append( str );
00706
00707 } else if ( cmd.startsWith( "TIMELONGEN" ) ) {
00708 kdDebug() << "Command: TIMELONGEN" << endl;
00709 i += strlen( "TIMELONGEN" );
00710 QDateTime date = QDateTime::currentDateTime();
00711 KLocale locale( "C");
00712 QString str = locale.formatTime( date.time(), true );
00713 body.append( str );
00714
00715 } else if ( cmd.startsWith( "TIMELONG" ) ) {
00716 kdDebug() << "Command: TIMELONG" << endl;
00717 i += strlen( "TIMELONG" );
00718 QDateTime date = QDateTime::currentDateTime();
00719 QString str = KGlobal::locale()->formatTime( date.time(), true );
00720 body.append( str );
00721
00722 } else if ( cmd.startsWith( "TIME" ) ) {
00723 kdDebug() << "Command: TIME" << endl;
00724 i += strlen( "TIME" );
00725 QDateTime date = QDateTime::currentDateTime();
00726 QString str = KGlobal::locale()->formatTime( date.time(), false );
00727 body.append( str );
00728
00729 } else if ( cmd.startsWith( "ODATEEN" ) ) {
00730 kdDebug() << "Command: ODATEEN" << endl;
00731 i += strlen( "ODATEEN" );
00732 if ( mOrigMsg ) {
00733 QDateTime date;
00734 date.setTime_t( mOrigMsg->date() );
00735 KLocale locale( "C");
00736 QString str = locale.formatDate( date.date(), false );
00737 body.append( str );
00738 }
00739
00740 } else if ( cmd.startsWith( "ODATESHORT") ) {
00741 kdDebug() << "Command: ODATESHORT" << endl;
00742 i += strlen( "ODATESHORT");
00743 if ( mOrigMsg ) {
00744 QDateTime date;
00745 date.setTime_t( mOrigMsg->date() );
00746 QString str = KGlobal::locale()->formatDate( date.date(), true );
00747 body.append( str );
00748 }
00749
00750 } else if ( cmd.startsWith( "ODATE") ) {
00751 kdDebug() << "Command: ODATE" << endl;
00752 i += strlen( "ODATE");
00753 if ( mOrigMsg ) {
00754 QDateTime date;
00755 date.setTime_t( mOrigMsg->date() );
00756 QString str = KGlobal::locale()->formatDate( date.date(), false );
00757 body.append( str );
00758 }
00759
00760 } else if ( cmd.startsWith( "ODOW") ) {
00761 kdDebug() << "Command: ODOW" << endl;
00762 i += strlen( "ODOW");
00763 if ( mOrigMsg ) {
00764 QDateTime date;
00765 date.setTime_t( mOrigMsg->date() );
00766 QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false );
00767 body.append( str );
00768 }
00769
00770 } else if ( cmd.startsWith( "OTIMELONGEN") ) {
00771 kdDebug() << "Command: OTIMELONGEN" << endl;
00772 i += strlen( "OTIMELONGEN");
00773 if ( mOrigMsg ) {
00774 QDateTime date;
00775 date.setTime_t( mOrigMsg->date() );
00776 KLocale locale( "C");
00777 QString str = locale.formatTime( date.time(), true );
00778 body.append( str );
00779 }
00780
00781 } else if ( cmd.startsWith( "OTIMELONG") ) {
00782 kdDebug() << "Command: OTIMELONG" << endl;
00783 i += strlen( "OTIMELONG");
00784 if ( mOrigMsg ) {
00785 QDateTime date;
00786 date.setTime_t( mOrigMsg->date() );
00787 QString str = KGlobal::locale()->formatTime( date.time(), true );
00788 body.append( str );
00789 }
00790
00791 } else if ( cmd.startsWith( "OTIME") ) {
00792 kdDebug() << "Command: OTIME" << endl;
00793 i += strlen( "OTIME");
00794 if ( mOrigMsg ) {
00795 QDateTime date;
00796 date.setTime_t( mOrigMsg->date() );
00797 QString str = KGlobal::locale()->formatTime( date.time(), false );
00798 body.append( str );
00799 }
00800
00801 } else if ( cmd.startsWith( "BLANK" ) ) {
00802
00803 kdDebug() << "Command: BLANK" << endl;
00804 i += strlen( "BLANK" );
00805
00806 } else if ( cmd.startsWith( "NOP" ) ) {
00807
00808 kdDebug() << "Command: NOP" << endl;
00809 i += strlen( "NOP" );
00810
00811 } else if ( cmd.startsWith( "CLEAR" ) ) {
00812
00813 kdDebug() << "Command: CLEAR" << endl;
00814 i += strlen( "CLEAR" );
00815 body = "";
00816 mMsg->setCursorPos( 0 );
00817
00818 } else if ( cmd.startsWith( "DEBUGOFF" ) ) {
00819
00820 kdDebug() << "Command: DEBUGOFF" << endl;
00821 i += strlen( "DEBUGOFF" );
00822 mDebug = false;
00823
00824 } else if ( cmd.startsWith( "DEBUG" ) ) {
00825
00826 kdDebug() << "Command: DEBUG" << endl;
00827 i += strlen( "DEBUG" );
00828 mDebug = true;
00829
00830 } else if ( cmd.startsWith( "CURSOR" ) ) {
00831
00832 kdDebug() << "Command: CURSOR" << endl;
00833 i += strlen( "CURSOR" );
00834 mMsg->setCursorPos( body.length() );
00835
00836 } else {
00837
00838 body.append( c );
00839 }
00840
00841 } else if ( dnl && ( c == '\n' || c == '\r') ) {
00842
00843 if ( ( c == '\n' && tmpl[i + 1] == '\r' ) ||
00844 ( c == '\r' && tmpl[i + 1] == '\n' ) ) {
00845
00846 i += 1;
00847 }
00848 dnl = false;
00849 } else {
00850 body.append( c );
00851 }
00852 }
00853
00854 addProcessedBodyToMessage( body );
00855 }
00856
00857 QString TemplateParser::messageText( bool allowSelectionOnly )
00858 {
00859 if ( !mSelection.isEmpty() && allowSelectionOnly )
00860 return mSelection;
00861
00862
00863 partNode *root = parsedObjectTree();
00864 return mOrigMsg->asPlainTextFromObjectTree( root, true, mAllowDecryption );
00865 }
00866
00867 partNode* TemplateParser::parsedObjectTree()
00868 {
00869 if ( mOrigRoot )
00870 return mOrigRoot;
00871
00872 mOrigRoot = partNode::fromMessage( mOrigMsg );
00873 KMail::ObjectTreeParser otp;
00874 otp.parseObjectTree( mOrigRoot );
00875 return mOrigRoot;
00876 }
00877
00878 void TemplateParser::addProcessedBodyToMessage( const QString &body )
00879 {
00880 if ( mAppend ) {
00881
00882
00883 QCString msg_body = mMsg->body();
00884 msg_body.append( body.utf8() );
00885 mMsg->setBody( msg_body );
00886 }
00887 else {
00888
00889
00890 partNode *root = parsedObjectTree();
00891 KMail::AttachmentCollector ac;
00892 ac.collectAttachmentsFrom( root );
00893
00894
00895
00896 mMsg->deleteBodyParts();
00897
00898
00899 if ( mMode == Forward ) {
00900 if ( !mTo.isEmpty() ) {
00901 mMsg->setTo( mMsg->to() + ',' + mTo );
00902 }
00903 if ( !mCC.isEmpty() )
00904 mMsg->setCc( mMsg->cc() + ',' + mCC );
00905 }
00906
00907
00908
00909 if ( ac.attachments().empty() || mMode != Forward ) {
00910 mMsg->headers().ContentType().FromString( DwString() );
00911 mMsg->headers().ContentType().Parse();
00912 mMsg->headers().ContentType().SetType( DwMime::kTypeText );
00913 mMsg->headers().ContentType().SetSubtype( DwMime::kSubtypePlain );
00914 mMsg->headers().Assemble();
00915 mMsg->setBodyFromUnicode( body );
00916 mMsg->assembleIfNeeded();
00917 }
00918
00919
00920
00921 else
00922 {
00923 mMsg->headers().ContentType().SetType( DwMime::kTypeMultipart );
00924 mMsg->headers().ContentType().SetSubtype( DwMime::kSubtypeMixed );
00925 mMsg->headers().ContentType().CreateBoundary( 0 );
00926
00927 KMMessagePart textPart;
00928 textPart.setBodyFromUnicode( body );
00929 mMsg->addDwBodyPart( mMsg->createDWBodyPart( &textPart ) );
00930 mMsg->assembleIfNeeded();
00931
00932 for ( std::vector<partNode*>::const_iterator it = ac.attachments().begin();
00933 it != ac.attachments().end(); ++it ) {
00934
00935
00936
00937
00938
00939 ( *it )->dwPart()->SetNext( 0 );
00940
00941 mMsg->addDwBodyPart( static_cast<DwBodyPart*>( ( *it )->dwPart()->Clone() ) );
00942 mMsg->assembleIfNeeded();
00943 }
00944 }
00945 }
00946 }
00947
00948 QString TemplateParser::findCustomTemplate( const QString &tmplName )
00949 {
00950 CTemplates t( tmplName );
00951 mTo = t.to();
00952 mCC = t.cC();
00953 QString content = t.content();
00954 if ( !content.isEmpty() ) {
00955 return content;
00956 } else {
00957 return findTemplate();
00958 }
00959 }
00960
00961 QString TemplateParser::findTemplate()
00962 {
00963
00964 if ( !GlobalSettings::self()->phrasesConverted() ) {
00965 TemplatesConfiguration::importFromPhrases();
00966 }
00967
00968
00969
00970 QString tmpl;
00971
00972 if ( !mFolder ) {
00973 mFolder = mMsg->parent();
00974 if ( !mFolder ) {
00975 if ( mOrigMsg ) {
00976 mFolder = mOrigMsg->parent();
00977 }
00978 if ( !mFolder ) {
00979 kdDebug(5006) << "Oops! No folder for message" << endl;
00980 }
00981 }
00982 }
00983 kdDebug(5006) << "Folder found: " << mFolder << endl;
00984
00985 if ( mFolder )
00986 {
00987 QString fid = mFolder->idString();
00988 Templates fconf( fid );
00989 if ( fconf.useCustomTemplates() ) {
00990 switch( mMode ) {
00991 case NewMessage:
00992 tmpl = fconf.templateNewMessage();
00993 break;
00994 case Reply:
00995 tmpl = fconf.templateReply();
00996 break;
00997 case ReplyAll:
00998 tmpl = fconf.templateReplyAll();
00999 break;
01000 case Forward:
01001 tmpl = fconf.templateForward();
01002 break;
01003 default:
01004 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
01005 return "";
01006 }
01007 mQuoteString = fconf.quoteString();
01008 if ( !tmpl.isEmpty() ) {
01009 return tmpl;
01010 }
01011 }
01012 }
01013
01014 if ( !mIdentity ) {
01015 mIdentity = mMsg->identityUoid();
01016 if ( !mIdentity && mOrigMsg ) {
01017 mIdentity = mOrigMsg->identityUoid();
01018 }
01019 mIdentity = kmkernel->identityManager()->identityForUoidOrDefault( mIdentity ).uoid();
01020 if ( !mIdentity ) {
01021 kdDebug(5006) << "Oops! No identity for message" << endl;
01022 }
01023 }
01024 kdDebug(5006) << "Identity found: " << mIdentity << endl;
01025
01026 QString iid;
01027 if ( mIdentity ) {
01028 iid = QString("IDENTITY_%1").arg( mIdentity );
01029 }
01030 else {
01031 iid = "IDENTITY_NO_IDENTITY";
01032 }
01033
01034 Templates iconf( iid );
01035 if ( iconf.useCustomTemplates() ) {
01036 switch( mMode ) {
01037 case NewMessage:
01038 tmpl = iconf.templateNewMessage();
01039 break;
01040 case Reply:
01041 tmpl = iconf.templateReply();
01042 break;
01043 case ReplyAll:
01044 tmpl = iconf.templateReplyAll();
01045 break;
01046 case Forward:
01047 tmpl = iconf.templateForward();
01048 break;
01049 default:
01050 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
01051 return "";
01052 }
01053 mQuoteString = iconf.quoteString();
01054 if ( !tmpl.isEmpty() ) {
01055 return tmpl;
01056 }
01057 }
01058
01059 switch( mMode ) {
01060 case NewMessage:
01061 tmpl = GlobalSettings::self()->templateNewMessage();
01062 break;
01063 case Reply:
01064 tmpl = GlobalSettings::self()->templateReply();
01065 break;
01066 case ReplyAll:
01067 tmpl = GlobalSettings::self()->templateReplyAll();
01068 break;
01069 case Forward:
01070 tmpl = GlobalSettings::self()->templateForward();
01071 break;
01072 default:
01073 kdDebug(5006) << "Unknown message mode: " << mMode << endl;
01074 return "";
01075 }
01076
01077 mQuoteString = GlobalSettings::self()->quoteString();
01078 return tmpl;
01079 }
01080
01081 QString TemplateParser::pipe( const QString &cmd, const QString &buf )
01082 {
01083 mPipeOut = "";
01084 mPipeErr = "";
01085 mPipeRc = 0;
01086
01087 KProcess proc;
01088 QCString data = buf.local8Bit();
01089
01090
01091
01092 proc << KShell::splitArgs( cmd, KShell::TildeExpand );
01093 proc.setUseShell( true );
01094 connect( &proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
01095 this, SLOT( onReceivedStdout( KProcess *, char *, int ) ) );
01096 connect( &proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
01097 this, SLOT( onReceivedStderr( KProcess *, char *, int ) ) );
01098 connect( &proc, SIGNAL( wroteStdin( KProcess * ) ),
01099 this, SLOT( onWroteStdin( KProcess * ) ) );
01100
01101 if ( proc.start( KProcess::NotifyOnExit, KProcess::All ) ) {
01102
01103 bool pipe_filled = proc.writeStdin( data, data.length() );
01104 if ( pipe_filled ) {
01105 proc.closeStdin();
01106
01107 bool exited = proc.wait( PipeTimeout );
01108 if ( exited ) {
01109
01110 if ( proc.normalExit() ) {
01111
01112 mPipeRc = proc.exitStatus();
01113 if ( mPipeRc != 0 && mDebug ) {
01114 if ( mPipeErr.isEmpty() ) {
01115 KMessageBox::error( 0,
01116 i18n( "Pipe command exit with status %1: %2").
01117 arg( mPipeRc ).arg( cmd ) );
01118 } else {
01119 KMessageBox::detailedError( 0,
01120 i18n( "Pipe command exit with status %1: %2" ).
01121 arg( mPipeRc ).arg( cmd ), mPipeErr );
01122 }
01123 }
01124
01125 } else {
01126
01127 mPipeRc = -( proc.exitSignal() );
01128 if ( mPipeRc != 0 && mDebug ) {
01129 if ( mPipeErr.isEmpty() ) {
01130 KMessageBox::error( 0,
01131 i18n( "Pipe command killed by signal %1: %2" ).
01132 arg( -(mPipeRc) ).arg( cmd ) );
01133 } else {
01134 KMessageBox::detailedError( 0,
01135 i18n( "Pipe command killed by signal %1: %2" ).
01136 arg( -(mPipeRc) ).arg( cmd ), mPipeErr );
01137 }
01138 }
01139 }
01140
01141 } else {
01142
01143 proc.kill();
01144 proc.detach();
01145 if ( mDebug ) {
01146 KMessageBox::error( 0,
01147 i18n( "Pipe command did not finish within %1 seconds: %2" ).
01148 arg( PipeTimeout ).arg( cmd ) );
01149 }
01150 }
01151
01152 } else {
01153
01154 proc.kill();
01155 proc.detach();
01156 if ( mDebug ) {
01157 if ( mPipeErr.isEmpty() ) {
01158 KMessageBox::error( 0,
01159 i18n( "Cannot write to process stdin: %1" ).arg( cmd ) );
01160 } else {
01161 KMessageBox::detailedError( 0,
01162 i18n( "Cannot write to process stdin: %1" ).
01163 arg( cmd ), mPipeErr );
01164 }
01165 }
01166 }
01167
01168 } else if ( mDebug ) {
01169 KMessageBox::error( 0,
01170 i18n( "Cannot start pipe command from template: %1" ).
01171 arg( cmd ) );
01172 }
01173
01174 return mPipeOut;
01175 }
01176
01177 void TemplateParser::onProcessExited( KProcess *proc )
01178 {
01179 Q_UNUSED( proc );
01180
01181 }
01182
01183 void TemplateParser::onReceivedStdout( KProcess *proc, char *buffer, int buflen )
01184 {
01185 Q_UNUSED( proc );
01186 mPipeOut += QString::fromLocal8Bit( buffer, buflen );
01187 }
01188
01189 void TemplateParser::onReceivedStderr( KProcess *proc, char *buffer, int buflen )
01190 {
01191 Q_UNUSED( proc );
01192 mPipeErr += QString::fromLocal8Bit( buffer, buflen );
01193 }
01194
01195 void TemplateParser::onWroteStdin( KProcess *proc )
01196 {
01197 proc->closeStdin();
01198 }
01199
01200 #include "templateparser.moc"