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