diff options
Diffstat (limited to 'kmail/templateparser.cpp')
-rw-r--r-- | kmail/templateparser.cpp | 1093 |
1 files changed, 1093 insertions, 0 deletions
diff --git a/kmail/templateparser.cpp b/kmail/templateparser.cpp new file mode 100644 index 000000000..39591358b --- /dev/null +++ b/kmail/templateparser.cpp @@ -0,0 +1,1093 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + * kmail: KDE mail client + * This file: Copyright (C) 2006 Dmitry Morozhnikov <dmiceman@mail.ru> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <config.h> + +#include <qstring.h> +#include <qdatetime.h> +#include <klocale.h> +#include <kcalendarsystem.h> +#include <kmime_util.h> +#include <kglobal.h> +#include <kprocess.h> +#include <qregexp.h> +#include <qfile.h> +#include <kmessagebox.h> +#include <kshell.h> +#include <qfileinfo.h> + +#include "kmmessage.h" +#include "kmmsgbase.h" +#include "kmfolder.h" +#include "templatesconfiguration.h" +#include "templatesconfiguration_kfg.h" +#include "customtemplates_kfg.h" +#include "globalsettings_base.h" +#include "kmkernel.h" +#include <libkpimidentities/identity.h> +#include <libkpimidentities/identitymanager.h> + +#include "templateparser.h" + +TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, + const QString aselection, + bool asmartQuote, bool anoQuote, + bool aallowDecryption, bool aselectionIsBody ) : + mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSelection( aselection ), + mSmartQuote( asmartQuote ), mNoQuote( anoQuote ), + mAllowDecryption( aallowDecryption ), mSelectionIsBody( aselectionIsBody ), + mDebug( false ), mQuoteString( "> " ), mAppend( false ) +{ + mMsg = amsg; +} + +int TemplateParser::parseQuotes( const QString &prefix, const QString &str, + QString "e ) const +{ + int pos = prefix.length(); + int len; + int str_len = str.length(); + QChar qc = '"'; + QChar prev = 0; + + pos++; + len = pos; + + while ( pos < str_len ) { + QChar c = str[pos]; + + pos++; + len++; + + if ( prev ) { + quote.append( c ); + prev = 0; + } else { + if ( c == '\\' ) { + prev = c; + } else if ( c == qc ) { + break; + } else { + quote.append( c ); + } + } + } + + return len; +} + +QString TemplateParser::getFName( const QString &str ) +{ + // simple logic: + // if there is ',' in name, than format is 'Last, First' + // else format is 'First Last' + // last resort -- return 'name' from 'name@domain' + int sep_pos; + QString res; + if ( ( sep_pos = str.find( '@' ) ) > 0 ) { + int i; + for ( i = (sep_pos - 1); i >= 0; --i ) { + QChar c = str[i]; + if ( c.isLetterOrNumber() ) { + res.prepend( c ); + } else { + break; + } + } + } else if ( ( sep_pos = str.find(',') ) > 0 ) { + unsigned int i; + bool begin = false; + for ( i = sep_pos; i < str.length(); ++i ) { + QChar c = str[i]; + if ( c.isLetterOrNumber() ) { + begin = true; + res.append( c ); + } else if ( begin ) { + break; + } + } + } else { + unsigned int i; + for ( i = 0; i < str.length(); ++i ) { + QChar c = str[i]; + if ( c.isLetterOrNumber() ) { + res.append( c ); + } else { + break; + } + } + } + return res; +} + +QString TemplateParser::getLName( const QString &str ) +{ + // simple logic: + // if there is ',' in name, than format is 'Last, First' + // else format is 'First Last' + int sep_pos; + QString res; + if ( ( sep_pos = str.find(',') ) > 0 ) { + int i; + for ( i = sep_pos; i >= 0; --i ) { + QChar c = str[i]; + if ( c.isLetterOrNumber() ) { + res.prepend( c ); + } else { + break; + } + } + } else { + if ( ( sep_pos = str.find( ' ' ) ) > 0 ) { + unsigned int i; + bool begin = false; + for ( i = sep_pos; i < str.length(); ++i ) { + QChar c = str[i]; + if ( c.isLetterOrNumber() ) { + begin = true; + res.append( c ); + } else if ( begin ) { + break; + } + } + } + } + return res; +} + +void TemplateParser::process( KMMessage *aorig_msg, KMFolder *afolder, bool append ) +{ + mAppend = append; + mOrigMsg = aorig_msg; + mFolder = afolder; + QString tmpl = findTemplate(); + return processWithTemplate( tmpl ); +} + +void TemplateParser::process( const QString &tmplName, KMMessage *aorig_msg, + KMFolder *afolder, bool append ) +{ + mAppend = append; + mOrigMsg = aorig_msg; + mFolder = afolder; + QString tmpl = findCustomTemplate( tmplName ); + return processWithTemplate( tmpl ); +} + +void TemplateParser::processWithTemplate( const QString &tmpl ) +{ + QString body; + int tmpl_len = tmpl.length(); + bool dnl = false; + for ( int i = 0; i < tmpl_len; ++i ) { + QChar c = tmpl[i]; + // kdDebug() << "Next char: " << c << endl; + if ( c == '%' ) { + QString cmd = tmpl.mid( i + 1 ); + + if ( cmd.startsWith( "-" ) ) { + // dnl + kdDebug() << "Command: -" << endl; + dnl = true; + i += 1; + + } else if ( cmd.startsWith( "REM=" ) ) { + // comments + kdDebug() << "Command: REM=" << endl; + QString q; + int len = parseQuotes( "REM=", cmd, q ); + i += len; + + } else if ( cmd.startsWith( "INSERT=" ) ) { + // insert content of specified file as is + kdDebug() << "Command: INSERT=" << endl; + QString q; + int len = parseQuotes( "INSERT=", cmd, q ); + i += len; + QString path = KShell::tildeExpand( q ); + QFileInfo finfo( path ); + if (finfo.isRelative() ) { + path = KShell::homeDir( "" ); + path += '/'; + path += q; + } + QFile file( path ); + if ( file.open( IO_ReadOnly ) ) { + QByteArray content = file.readAll(); + QString str = QString::fromLocal8Bit( content, content.size() ); + body.append( str ); + } else if ( mDebug ) { + KMessageBox::error( 0, + i18n( "Cannot insert content from file %1: %2" ). + arg( path ).arg( file.errorString() ) ); + } + + } else if ( cmd.startsWith( "SYSTEM=" ) ) { + // insert content of specified file as is + kdDebug() << "Command: SYSTEM=" << endl; + QString q; + int len = parseQuotes( "SYSTEM=", cmd, q ); + i += len; + QString pipe_cmd = q; + QString str = pipe( pipe_cmd, "" ); + body.append( str ); + + } else if ( cmd.startsWith( "PUT=" ) ) { + // insert content of specified file as is + kdDebug() << "Command: PUT=" << endl; + QString q; + int len = parseQuotes( "PUT=", cmd, q ); + i += len; + QString path = KShell::tildeExpand( q ); + QFileInfo finfo( path ); + if (finfo.isRelative() ) { + path = KShell::homeDir( "" ); + path += '/'; + path += q; + } + QFile file( path ); + if ( file.open( IO_ReadOnly ) ) { + QByteArray content = file.readAll(); + body.append( QString::fromLocal8Bit( content, content.size() ) ); + } else if ( mDebug ) { + KMessageBox::error( 0, + i18n( "Cannot insert content from file %1: %2"). + arg( path ).arg(file.errorString() )); + } + + } else if ( cmd.startsWith( "QUOTEPIPE=" ) ) { + // pipe message body throw command and insert it as quotation + kdDebug() << "Command: QUOTEPIPE=" << endl; + QString q; + int len = parseQuotes( "QUOTEPIPE=", cmd, q ); + i += len; + QString pipe_cmd = q; + if ( mOrigMsg && !mNoQuote ) { + QString str = pipe( pipe_cmd, mSelection ); + QString quote = mOrigMsg->asQuotedString( "", mQuoteString, str, + mSmartQuote, mAllowDecryption ); + body.append( quote ); + } + + } else if ( cmd.startsWith( "QUOTE" ) ) { + kdDebug() << "Command: QUOTE" << endl; + i += strlen( "QUOTE" ); + if ( mOrigMsg && !mNoQuote ) { + QString quote = mOrigMsg->asQuotedString( "", mQuoteString, mSelection, + mSmartQuote, mAllowDecryption ); + body.append( quote ); + } + + } else if ( cmd.startsWith( "QHEADERS" ) ) { + kdDebug() << "Command: QHEADERS" << endl; + i += strlen( "QHEADERS" ); + if ( mOrigMsg && !mNoQuote ) { + QString quote = mOrigMsg->asQuotedString( "", mQuoteString, + mOrigMsg->headerAsSendableString(), + mSmartQuote, false ); + body.append( quote ); + } + + } else if ( cmd.startsWith( "HEADERS" ) ) { + kdDebug() << "Command: HEADERS" << endl; + i += strlen( "HEADERS" ); + if ( mOrigMsg && !mNoQuote ) { + QString str = mOrigMsg->headerAsSendableString(); + body.append( str ); + } + + } else if ( cmd.startsWith( "TEXTPIPE=" ) ) { + // pipe message body throw command and insert it as is + kdDebug() << "Command: TEXTPIPE=" << endl; + QString q; + int len = parseQuotes( "TEXTPIPE=", cmd, q ); + i += len; + QString pipe_cmd = q; + if ( mOrigMsg ) { + QString str = pipe(pipe_cmd, mSelection ); + body.append( str ); + } + + } else if ( cmd.startsWith( "MSGPIPE=" ) ) { + // pipe full message throw command and insert result as is + kdDebug() << "Command: MSGPIPE=" << endl; + QString q; + int len = parseQuotes( "MSGPIPE=", cmd, q ); + i += len; + QString pipe_cmd = q; + if ( mOrigMsg ) { + QString str = pipe(pipe_cmd, mOrigMsg->asString() ); + body.append( str ); + } + + } else if ( cmd.startsWith( "BODYPIPE=" ) ) { + // pipe message body generated so far throw command and insert result as is + kdDebug() << "Command: BODYPIPE=" << endl; + QString q; + int len = parseQuotes( "BODYPIPE=", cmd, q ); + i += len; + QString pipe_cmd = q; + QString str = pipe( pipe_cmd, body ); + body.append( str ); + + } else if ( cmd.startsWith( "CLEARPIPE=" ) ) { + // pipe message body generated so far throw command and + // insert result as is replacing current body + kdDebug() << "Command: CLEARPIPE=" << endl; + QString q; + int len = parseQuotes( "CLEARPIPE=", cmd, q ); + i += len; + QString pipe_cmd = q; + QString str = pipe( pipe_cmd, body ); + body = str; + mMsg->setCursorPos( 0 ); + + } else if ( cmd.startsWith( "TEXT" ) ) { + kdDebug() << "Command: TEXT" << endl; + i += strlen( "TEXT" ); + if ( mOrigMsg ) { + QString quote = mOrigMsg->asPlainText( false, mAllowDecryption ); + body.append( quote ); + } + + } else if ( cmd.startsWith( "OTEXTSIZE" ) ) { + kdDebug() << "Command: OTEXTSIZE" << endl; + i += strlen( "OTEXTSIZE" ); + if ( mOrigMsg ) { + QString str = QString( "%1" ).arg( mOrigMsg->body().length() ); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTEXT" ) ) { + kdDebug() << "Command: OTEXT" << endl; + i += strlen( "OTEXT" ); + if ( mOrigMsg ) { + QString quote = mOrigMsg->asPlainText( false, mAllowDecryption ); + body.append( quote ); + } + + } else if ( cmd.startsWith( "CCADDR" ) ) { + kdDebug() << "Command: CCADDR" << endl; + i += strlen( "CCADDR" ); + QString str = mMsg->cc(); + body.append( str ); + + } else if ( cmd.startsWith( "CCNAME" ) ) { + kdDebug() << "Command: CCNAME" << endl; + i += strlen( "CCNAME" ); + QString str = mMsg->ccStrip(); + body.append( str ); + + } else if ( cmd.startsWith( "CCFNAME" ) ) { + kdDebug() << "Command: CCFNAME" << endl; + i += strlen( "CCFNAME" ); + QString str = mMsg->ccStrip(); + body.append( getFName( str ) ); + + } else if ( cmd.startsWith( "CCLNAME" ) ) { + kdDebug() << "Command: CCLNAME" << endl; + i += strlen( "CCLNAME" ); + QString str = mMsg->ccStrip(); + body.append( getLName( str ) ); + + } else if ( cmd.startsWith( "TOADDR" ) ) { + kdDebug() << "Command: TOADDR" << endl; + i += strlen( "TOADDR" ); + QString str = mMsg->to(); + body.append( str ); + + } else if ( cmd.startsWith( "TONAME" ) ) { + kdDebug() << "Command: TONAME" << endl; + i += strlen( "TONAME" ); + QString str = mMsg->toStrip(); + body.append( str ); + + } else if ( cmd.startsWith( "TOFNAME" ) ) { + kdDebug() << "Command: TOFNAME" << endl; + i += strlen( "TOFNAME" ); + QString str = mMsg->toStrip(); + body.append( getFName( str ) ); + + } else if ( cmd.startsWith( "TOLNAME" ) ) { + kdDebug() << "Command: TOLNAME" << endl; + i += strlen( "TOLNAME" ); + QString str = mMsg->toStrip(); + body.append( getLName( str ) ); + + } else if ( cmd.startsWith( "TOLIST" ) ) { + kdDebug() << "Command: TOLIST" << endl; + i += strlen( "TOLIST" ); + QString str = mMsg->to(); + body.append( str ); + + } else if ( cmd.startsWith( "FROMADDR" ) ) { + kdDebug() << "Command: FROMADDR" << endl; + i += strlen( "FROMADDR" ); + QString str = mMsg->from(); + body.append( str ); + + } else if ( cmd.startsWith( "FROMNAME" ) ) { + kdDebug() << "Command: FROMNAME" << endl; + i += strlen( "FROMNAME" ); + QString str = mMsg->fromStrip(); + body.append( str ); + + } else if ( cmd.startsWith( "FROMFNAME" ) ) { + kdDebug() << "Command: FROMFNAME" << endl; + i += strlen( "FROMFNAME" ); + QString str = mMsg->fromStrip(); + body.append( getFName( str ) ); + + } else if ( cmd.startsWith( "FROMLNAME" ) ) { + kdDebug() << "Command: FROMLNAME" << endl; + i += strlen( "FROMLNAME" ); + QString str = mMsg->fromStrip(); + body.append( getLName( str ) ); + + } else if ( cmd.startsWith( "FULLSUBJECT" ) ) { + kdDebug() << "Command: FULLSUBJECT" << endl; + i += strlen( "FULLSUBJECT" ); + QString str = mMsg->subject(); + body.append( str ); + + } else if ( cmd.startsWith( "FULLSUBJ" ) ) { + kdDebug() << "Command: FULLSUBJ" << endl; + i += strlen( "FULLSUBJ" ); + QString str = mMsg->subject(); + body.append( str ); + + } else if ( cmd.startsWith( "MSGID" ) ) { + kdDebug() << "Command: MSGID" << endl; + i += strlen( "MSGID" ); + QString str = mMsg->id(); + body.append( str ); + + } else if ( cmd.startsWith( "OHEADER=" ) ) { + // insert specified content of header from original message + kdDebug() << "Command: OHEADER=" << endl; + QString q; + int len = parseQuotes( "OHEADER=", cmd, q ); + i += len; + if ( mOrigMsg ) { + QString hdr = q; + QString str = mOrigMsg->headerFields(hdr.local8Bit() ).join( ", " ); + body.append( str ); + } + + } else if ( cmd.startsWith( "HEADER=" ) ) { + // insert specified content of header from current message + kdDebug() << "Command: HEADER=" << endl; + QString q; + int len = parseQuotes( "HEADER=", cmd, q ); + i += len; + QString hdr = q; + QString str = mMsg->headerFields(hdr.local8Bit() ).join( ", " ); + body.append( str ); + + } else if ( cmd.startsWith( "HEADER( " ) ) { + // insert specified content of header from current message + kdDebug() << "Command: HEADER( " << endl; + QRegExp re = QRegExp( "^HEADER\\((.+)\\)" ); + re.setMinimal( true ); + int res = re.search( cmd ); + if ( res != 0 ) { + // something wrong + i += strlen( "HEADER( " ); + } else { + i += re.matchedLength(); + QString hdr = re.cap( 1 ); + QString str = mMsg->headerFields( hdr.local8Bit() ).join( ", " ); + body.append( str ); + } + + } else if ( cmd.startsWith( "OCCADDR" ) ) { + kdDebug() << "Command: OCCADDR" << endl; + i += strlen( "OCCADDR" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->cc(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OCCNAME" ) ) { + kdDebug() << "Command: OCCNAME" << endl; + i += strlen( "OCCNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->ccStrip(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OCCFNAME" ) ) { + kdDebug() << "Command: OCCFNAME" << endl; + i += strlen( "OCCFNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->ccStrip(); + body.append( getFName( str ) ); + } + + } else if ( cmd.startsWith( "OCCLNAME" ) ) { + kdDebug() << "Command: OCCLNAME" << endl; + i += strlen( "OCCLNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->ccStrip(); + body.append( getLName( str ) ); + } + + } else if ( cmd.startsWith( "OTOADDR" ) ) { + kdDebug() << "Command: OTOADDR" << endl; + i += strlen( "OTOADDR" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->to(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTONAME" ) ) { + kdDebug() << "Command: OTONAME" << endl; + i += strlen( "OTONAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->toStrip(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTOFNAME" ) ) { + kdDebug() << "Command: OTOFNAME" << endl; + i += strlen( "OTOFNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->toStrip(); + body.append( getFName( str ) ); + } + + } else if ( cmd.startsWith( "OTOLNAME" ) ) { + kdDebug() << "Command: OTOLNAME" << endl; + i += strlen( "OTOLNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->toStrip(); + body.append( getLName( str ) ); + } + + } else if ( cmd.startsWith( "OTOLIST" ) ) { + kdDebug() << "Command: OTOLIST" << endl; + i += strlen( "OTOLIST" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->to(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTO" ) ) { + kdDebug() << "Command: OTO" << endl; + i += strlen( "OTO" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->to(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OFROMADDR" ) ) { + kdDebug() << "Command: OFROMADDR" << endl; + i += strlen( "OFROMADDR" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->from(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OFROMNAME" ) ) { + kdDebug() << "Command: OFROMNAME" << endl; + i += strlen( "OFROMNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->fromStrip(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OFROMFNAME" ) ) { + kdDebug() << "Command: OFROMFNAME" << endl; + i += strlen( "OFROMFNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->fromStrip(); + body.append( getFName( str ) ); + } + + } else if ( cmd.startsWith( "OFROMLNAME" ) ) { + kdDebug() << "Command: OFROMLNAME" << endl; + i += strlen( "OFROMLNAME" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->fromStrip(); + body.append( getLName( str ) ); + } + + } else if ( cmd.startsWith( "OFULLSUBJECT" ) ) { + kdDebug() << "Command: OFULLSUBJECT" << endl; + i += strlen( "OFULLSUBJECT" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->subject(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OFULLSUBJ" ) ) { + kdDebug() << "Command: OFULLSUBJ" << endl; + i += strlen( "OFULLSUBJ" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->subject(); + body.append( str ); + } + + } else if ( cmd.startsWith( "OMSGID" ) ) { + kdDebug() << "Command: OMSGID" << endl; + i += strlen( "OMSGID" ); + if ( mOrigMsg ) { + QString str = mOrigMsg->id(); + body.append( str ); + } + + } else if ( cmd.startsWith( "DATEEN" ) ) { + kdDebug() << "Command: DATEEN" << endl; + i += strlen( "DATEEN" ); + QDateTime date = QDateTime::currentDateTime(); + KLocale locale( "C" ); + QString str = locale.formatDate( date.date(), false ); + body.append( str ); + + } else if ( cmd.startsWith( "DATESHORT" ) ) { + kdDebug() << "Command: DATESHORT" << endl; + i += strlen( "DATESHORT" ); + QDateTime date = QDateTime::currentDateTime(); + QString str = KGlobal::locale()->formatDate( date.date(), true ); + body.append( str ); + + } else if ( cmd.startsWith( "DATE" ) ) { + kdDebug() << "Command: DATE" << endl; + i += strlen( "DATE" ); + QDateTime date = QDateTime::currentDateTime(); + QString str = KGlobal::locale()->formatDate( date.date(), false ); + body.append( str ); + + } else if ( cmd.startsWith( "DOW" ) ) { + kdDebug() << "Command: DOW" << endl; + i += strlen( "DOW" ); + QDateTime date = QDateTime::currentDateTime(); + QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false ); + body.append( str ); + + } else if ( cmd.startsWith( "TIMELONGEN" ) ) { + kdDebug() << "Command: TIMELONGEN" << endl; + i += strlen( "TIMELONGEN" ); + QDateTime date = QDateTime::currentDateTime(); + KLocale locale( "C"); + QString str = locale.formatTime( date.time(), true ); + body.append( str ); + + } else if ( cmd.startsWith( "TIMELONG" ) ) { + kdDebug() << "Command: TIMELONG" << endl; + i += strlen( "TIMELONG" ); + QDateTime date = QDateTime::currentDateTime(); + QString str = KGlobal::locale()->formatTime( date.time(), true ); + body.append( str ); + + } else if ( cmd.startsWith( "TIME" ) ) { + kdDebug() << "Command: TIME" << endl; + i += strlen( "TIME" ); + QDateTime date = QDateTime::currentDateTime(); + QString str = KGlobal::locale()->formatTime( date.time(), false ); + body.append( str ); + + } else if ( cmd.startsWith( "ODATEEN" ) ) { + kdDebug() << "Command: ODATEEN" << endl; + i += strlen( "ODATEEN" ); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + KLocale locale( "C"); + QString str = locale.formatDate( date.date(), false ); + body.append( str ); + } + + } else if ( cmd.startsWith( "ODATESHORT") ) { + kdDebug() << "Command: ODATESHORT" << endl; + i += strlen( "ODATESHORT"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + QString str = KGlobal::locale()->formatDate( date.date(), true ); + body.append( str ); + } + + } else if ( cmd.startsWith( "ODATE") ) { + kdDebug() << "Command: ODATE" << endl; + i += strlen( "ODATE"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + QString str = KGlobal::locale()->formatDate( date.date(), false ); + body.append( str ); + } + + } else if ( cmd.startsWith( "ODOW") ) { + kdDebug() << "Command: ODOW" << endl; + i += strlen( "ODOW"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + QString str = KGlobal::locale()->calendar()->weekDayName( date.date(), false ); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTIMELONGEN") ) { + kdDebug() << "Command: OTIMELONGEN" << endl; + i += strlen( "OTIMELONGEN"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + KLocale locale( "C"); + QString str = locale.formatTime( date.time(), true ); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTIMELONG") ) { + kdDebug() << "Command: OTIMELONG" << endl; + i += strlen( "OTIMELONG"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + QString str = KGlobal::locale()->formatTime( date.time(), true ); + body.append( str ); + } + + } else if ( cmd.startsWith( "OTIME") ) { + kdDebug() << "Command: OTIME" << endl; + i += strlen( "OTIME"); + if ( mOrigMsg ) { + QDateTime date; + date.setTime_t( mOrigMsg->date() ); + QString str = KGlobal::locale()->formatTime( date.time(), false ); + body.append( str ); + } + + } else if ( cmd.startsWith( "BLANK" ) ) { + // do nothing + kdDebug() << "Command: BLANK" << endl; + i += strlen( "BLANK" ); + + } else if ( cmd.startsWith( "NOP" ) ) { + // do nothing + kdDebug() << "Command: NOP" << endl; + i += strlen( "NOP" ); + + } else if ( cmd.startsWith( "CLEAR" ) ) { + // clear body buffer; not too useful yet + kdDebug() << "Command: CLEAR" << endl; + i += strlen( "CLEAR" ); + body = ""; + mMsg->setCursorPos( 0 ); + + } else if ( cmd.startsWith( "DEBUGOFF" ) ) { + // turn off debug + kdDebug() << "Command: DEBUGOFF" << endl; + i += strlen( "DEBUGOFF" ); + mDebug = false; + + } else if ( cmd.startsWith( "DEBUG" ) ) { + // turn on debug + kdDebug() << "Command: DEBUG" << endl; + i += strlen( "DEBUG" ); + mDebug = true; + + } else if ( cmd.startsWith( "CURSOR" ) ) { + // turn on debug + kdDebug() << "Command: CURSOR" << endl; + i += strlen( "CURSOR" ); + mMsg->setCursorPos( body.length() ); + + } else { + // wrong command, do nothing + body.append( c ); + } + + } else if ( dnl && ( c == '\n' || c == '\r') ) { + // skip + if ( ( c == '\n' && tmpl[i + 1] == '\r' ) || + ( c == '\r' && tmpl[i + 1] == '\n' ) ) { + // skip one more + i += 1; + } + dnl = false; + } else { + body.append( c ); + } + } + + // kdDebug() << "Message body: " << body << endl; + + if ( mAppend ) { + QCString msg_body = mMsg->body(); + msg_body.append( body.utf8() ); + mMsg->setBody( msg_body ); + } else { + mMsg->setBodyFromUnicode( body ); + } +} + +QString TemplateParser::findCustomTemplate( const QString &tmplName ) +{ + CTemplates t( tmplName ); + QString content = t.content(); + if ( !content.isEmpty() ) { + return content; + } else { + return findTemplate(); + } +} + +QString TemplateParser::findTemplate() +{ + // import 'Phrases' if it not done yet + if ( !GlobalSettings::self()->phrasesConverted() ) { + TemplatesConfiguration::importFromPhrases(); + } + + // kdDebug() << "Trying to find template for mode " << mode << endl; + + QString tmpl; + + if ( !mFolder ) { // find folder message belongs to + mFolder = mMsg->parent(); + if ( !mFolder ) { + if ( mOrigMsg ) { + mFolder = mOrigMsg->parent(); + } + if ( !mFolder ) { + kdDebug(5006) << "Oops! No folder for message" << endl; + } + } + } + kdDebug(5006) << "Folder found: " << mFolder << endl; + + if ( mFolder ) // only if a folder was found + { + QString fid = mFolder->idString(); + Templates fconf( fid ); + if ( fconf.useCustomTemplates() ) { // does folder use custom templates? + switch( mMode ) { + case NewMessage: + tmpl = fconf.templateNewMessage(); + break; + case Reply: + tmpl = fconf.templateReply(); + break; + case ReplyAll: + tmpl = fconf.templateReplyAll(); + break; + case Forward: + tmpl = fconf.templateForward(); + break; + default: + kdDebug(5006) << "Unknown message mode: " << mMode << endl; + return ""; + } + mQuoteString = fconf.quoteString(); + if ( !tmpl.isEmpty() ) { + return tmpl; // use folder-specific template + } + } + } + + if ( !mIdentity ) { // find identity message belongs to + mIdentity = mMsg->identityUoid(); + if ( !mIdentity && mOrigMsg ) { + mIdentity = mOrigMsg->identityUoid(); + } + mIdentity = kmkernel->identityManager()->identityForUoidOrDefault( mIdentity ).uoid(); + if ( !mIdentity ) { + kdDebug(5006) << "Oops! No identity for message" << endl; + } + } + kdDebug(5006) << "Identity found: " << mIdentity << endl; + + QString iid; + if ( mIdentity ) { + iid = QString("IDENTITY_%1").arg( mIdentity ); // templates ID for that identity + } + else { + iid = "IDENTITY_NO_IDENTITY"; // templates ID for no identity + } + + Templates iconf( iid ); + if ( iconf.useCustomTemplates() ) { // does identity use custom templates? + switch( mMode ) { + case NewMessage: + tmpl = iconf.templateNewMessage(); + break; + case Reply: + tmpl = iconf.templateReply(); + break; + case ReplyAll: + tmpl = iconf.templateReplyAll(); + break; + case Forward: + tmpl = iconf.templateForward(); + break; + default: + kdDebug(5006) << "Unknown message mode: " << mMode << endl; + return ""; + } + mQuoteString = iconf.quoteString(); + if ( !tmpl.isEmpty() ) { + return tmpl; // use identity-specific template + } + } + + switch( mMode ) { // use the global template + case NewMessage: + tmpl = GlobalSettings::self()->templateNewMessage(); + break; + case Reply: + tmpl = GlobalSettings::self()->templateReply(); + break; + case ReplyAll: + tmpl = GlobalSettings::self()->templateReplyAll(); + break; + case Forward: + tmpl = GlobalSettings::self()->templateForward(); + break; + default: + kdDebug(5006) << "Unknown message mode: " << mMode << endl; + return ""; + } + + mQuoteString = GlobalSettings::self()->quoteString(); + return tmpl; +} + +QString TemplateParser::pipe( const QString &cmd, const QString &buf ) +{ + mPipeOut = ""; + mPipeErr = ""; + mPipeRc = 0; + + KProcess proc; + QCString data = buf.local8Bit(); + + // kdDebug() << "Command data: " << data << endl; + + proc << KShell::splitArgs( cmd, KShell::TildeExpand ); + proc.setUseShell( true ); + connect( &proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ), + this, SLOT( onReceivedStdout( KProcess *, char *, int ) ) ); + connect( &proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ), + this, SLOT( onReceivedStderr( KProcess *, char *, int ) ) ); + connect( &proc, SIGNAL( wroteStdin( KProcess * ) ), + this, SLOT( onWroteStdin( KProcess * ) ) ); + + if ( proc.start( KProcess::NotifyOnExit, KProcess::All ) ) { + + bool pipe_filled = proc.writeStdin( data, data.length() ); + if ( pipe_filled ) { + proc.closeStdin(); + + bool exited = proc.wait( PipeTimeout ); + if ( exited ) { + + if ( proc.normalExit() ) { + + mPipeRc = proc.exitStatus(); + if ( mPipeRc != 0 && mDebug ) { + if ( mPipeErr.isEmpty() ) { + KMessageBox::error( 0, + i18n( "Pipe command exit with status %1: %2"). + arg( mPipeRc ).arg( cmd ) ); + } else { + KMessageBox::detailedError( 0, + i18n( "Pipe command exit with status %1: %2" ). + arg( mPipeRc ).arg( cmd ), mPipeErr ); + } + } + + } else { + + mPipeRc = -( proc.exitSignal() ); + if ( mPipeRc != 0 && mDebug ) { + if ( mPipeErr.isEmpty() ) { + KMessageBox::error( 0, + i18n( "Pipe command killed by signal %1: %2" ). + arg( -(mPipeRc) ).arg( cmd ) ); + } else { + KMessageBox::detailedError( 0, + i18n( "Pipe command killed by signal %1: %2" ). + arg( -(mPipeRc) ).arg( cmd ), mPipeErr ); + } + } + } + + } else { + // process does not exited after TemplateParser::PipeTimeout seconds, kill it + proc.kill(); + proc.detach(); + if ( mDebug ) { + KMessageBox::error( 0, + i18n( "Pipe command did not finish within %1 seconds: %2" ). + arg( PipeTimeout ).arg( cmd ) ); + } + } + + } else { + // can`t write to stdin of process + proc.kill(); + proc.detach(); + if ( mDebug ) { + if ( mPipeErr.isEmpty() ) { + KMessageBox::error( 0, + i18n( "Cannot write to process stdin: %1" ).arg( cmd ) ); + } else { + KMessageBox::detailedError( 0, + i18n( "Cannot write to process stdin: %1" ). + arg( cmd ), mPipeErr ); + } + } + } + + } else if ( mDebug ) { + KMessageBox::error( 0, + i18n( "Cannot start pipe command from template: %1" ). + arg( cmd ) ); + } + + return mPipeOut; +} + +void TemplateParser::onProcessExited( KProcess *proc ) +{ + Q_UNUSED( proc ); + // do nothing for now +} + +void TemplateParser::onReceivedStdout( KProcess *proc, char *buffer, int buflen ) +{ + Q_UNUSED( proc ); + mPipeOut += QString::fromLocal8Bit( buffer, buflen ); +} + +void TemplateParser::onReceivedStderr( KProcess *proc, char *buffer, int buflen ) +{ + Q_UNUSED( proc ); + mPipeErr += QString::fromLocal8Bit( buffer, buflen ); +} + +void TemplateParser::onWroteStdin( KProcess *proc ) +{ + proc->closeStdin(); +} + +#include "templateparser.moc" |