kpimidentities
signature.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "signature.h"
00022
00023 #include <kdebug.h>
00024 #include <klocale.h>
00025 #include <kmessagebox.h>
00026 #include <kconfiggroup.h>
00027 #include <kurl.h>
00028 #include <kprocess.h>
00029 #include <KRichTextEdit>
00030 #include <kpimutils/kfileio.h>
00031
00032 #include <QFileInfo>
00033 #include <assert.h>
00034
00035 using namespace KPIMIdentities;
00036
00037 Signature::Signature()
00038 : mType( Disabled ),
00039 mInlinedHtml( false )
00040 {}
00041
00042 Signature::Signature( const QString &text )
00043 : mText( text ),
00044 mType( Inlined ),
00045 mInlinedHtml( false )
00046 {}
00047
00048 Signature::Signature( const QString &url, bool isExecutable )
00049 : mUrl( url ),
00050 mType( isExecutable ? FromCommand : FromFile ),
00051 mInlinedHtml( false )
00052 {}
00053
00054 QString Signature::rawText( bool *ok ) const
00055 {
00056 switch ( mType ) {
00057 case Disabled:
00058 if ( ok ) {
00059 *ok = true;
00060 }
00061 return QString();
00062 case Inlined:
00063 if ( ok ) {
00064 *ok = true;
00065 }
00066 return mText;
00067 case FromFile:
00068 return textFromFile( ok );
00069 case FromCommand:
00070 return textFromCommand( ok );
00071 };
00072 kFatal(5325) << "Signature::type() returned unknown value!";
00073 return QString();
00074 }
00075
00076 QString Signature::textFromCommand( bool *ok ) const
00077 {
00078 assert( mType == FromCommand );
00079
00080
00081 if ( mUrl.isEmpty() ) {
00082 if ( ok ) {
00083 *ok = true;
00084 }
00085 return QString();
00086 }
00087
00088
00089 KProcess proc;
00090 proc.setOutputChannelMode( KProcess::SeparateChannels );
00091 proc.setShellCommand( mUrl );
00092 int rc = proc.execute();
00093
00094
00095 if ( rc != 0 ) {
00096 if ( ok ) {
00097 *ok = false;
00098 }
00099 QString wmsg = i18n( "<qt>Failed to execute signature script<p><b>%1</b>:</p>"
00100 "<p>%2</p></qt>", mUrl, QString( proc.readAllStandardError() ) );
00101 KMessageBox::error( 0, wmsg );
00102 return QString();
00103 }
00104
00105
00106 if ( ok ) {
00107 *ok = true;
00108 }
00109
00110
00111 QByteArray output = proc.readAllStandardOutput();
00112
00113
00114 return QString::fromLocal8Bit( output.data(), output.size() );
00115 }
00116
00117 QString Signature::textFromFile( bool *ok ) const
00118 {
00119 assert( mType == FromFile );
00120
00121
00122 if ( !KUrl( mUrl ).isLocalFile() &&
00123 !( QFileInfo( mUrl ).isRelative() &&
00124 QFileInfo( mUrl ).exists() ) ) {
00125 kDebug(5325) << "Signature::textFromFile:"
00126 << "non-local URLs are unsupported";
00127 if ( ok ) {
00128 *ok = false;
00129 }
00130 return QString();
00131 }
00132
00133 if ( ok ) {
00134 *ok = true;
00135 }
00136
00137
00138 const QByteArray ba = KPIMUtils::kFileToByteArray( mUrl, false );
00139 return QString::fromLocal8Bit( ba.data(), ba.size() );
00140 }
00141
00142 QString Signature::withSeparator( bool *ok ) const
00143 {
00144 QString signature = rawText( ok );
00145 if ( ok && (*ok) == false )
00146 return QString();
00147
00148 if ( signature.isEmpty() ) {
00149 return signature;
00150 }
00151
00152 QString newline = ( isInlinedHtml() && mType == Inlined ) ? "<br>" : "\n";
00153 if ( signature.startsWith( QString::fromLatin1( "-- " ) + newline )
00154 || ( signature.indexOf( newline + QString::fromLatin1( "-- " ) +
00155 newline ) != -1 ) ) {
00156
00157 return signature;
00158 } else {
00159
00160 return QString::fromLatin1( "-- " ) + newline + signature;
00161 }
00162 }
00163
00164 void Signature::setUrl( const QString &url, bool isExecutable )
00165 {
00166 mUrl = url;
00167 mType = isExecutable ? FromCommand : FromFile;
00168 }
00169
00170 void Signature::setInlinedHtml( bool isHtml )
00171 {
00172 mInlinedHtml = isHtml;
00173 }
00174
00175 bool Signature::isInlinedHtml() const
00176 {
00177 return mInlinedHtml;
00178 }
00179
00180
00181 static const char sigTypeKey[] = "Signature Type";
00182 static const char sigTypeInlineValue[] = "inline";
00183 static const char sigTypeFileValue[] = "file";
00184 static const char sigTypeCommandValue[] = "command";
00185 static const char sigTypeDisabledValue[] = "disabled";
00186 static const char sigTextKey[] = "Inline Signature";
00187 static const char sigFileKey[] = "Signature File";
00188 static const char sigCommandKey[] = "Signature Command";
00189 static const char sigTypeInlinedHtmlKey[] = "Inlined Html";
00190
00191 void Signature::readConfig( const KConfigGroup &config )
00192 {
00193 QString sigType = config.readEntry( sigTypeKey );
00194 if ( sigType == sigTypeInlineValue ) {
00195 mType = Inlined;
00196 mInlinedHtml = config.readEntry( sigTypeInlinedHtmlKey, false );
00197 } else if ( sigType == sigTypeFileValue ) {
00198 mType = FromFile;
00199 mUrl = config.readPathEntry( sigFileKey, QString() );
00200 } else if ( sigType == sigTypeCommandValue ) {
00201 mType = FromCommand;
00202 mUrl = config.readPathEntry( sigCommandKey, QString() );
00203 } else {
00204 mType = Disabled;
00205 }
00206 mText = config.readEntry( sigTextKey );
00207 }
00208
00209 void Signature::writeConfig( KConfigGroup &config ) const
00210 {
00211 switch ( mType ) {
00212 case Inlined:
00213 config.writeEntry( sigTypeKey, sigTypeInlineValue );
00214 config.writeEntry( sigTypeInlinedHtmlKey, mInlinedHtml );
00215 break;
00216 case FromFile:
00217 config.writeEntry( sigTypeKey, sigTypeFileValue );
00218 config.writePathEntry( sigFileKey, mUrl );
00219 break;
00220 case FromCommand:
00221 config.writeEntry( sigTypeKey, sigTypeCommandValue );
00222 config.writePathEntry( sigCommandKey, mUrl );
00223 break;
00224 case Disabled:
00225 config.writeEntry( sigTypeKey, sigTypeDisabledValue );
00226 default:
00227 break;
00228 }
00229 config.writeEntry( sigTextKey, mText );
00230 }
00231
00232 void Signature::insertIntoTextEdit( KRichTextEdit *textEdit,
00233 Placement placement, bool addSeparator )
00234 {
00235 QString signature;
00236 if ( addSeparator )
00237 signature = withSeparator();
00238 else
00239 signature = rawText();
00240
00241 insertPlainSignatureIntoTextEdit( signature, textEdit, placement,
00242 ( isInlinedHtml() &&
00243 type() == KPIMIdentities::Signature::Inlined ) );
00244 }
00245
00246 void Signature::insertPlainSignatureIntoTextEdit( const QString &signature, KRichTextEdit *textEdit,
00247 Signature::Placement placement, bool isHtml )
00248 {
00249 if ( !signature.isEmpty() ) {
00250
00251
00252
00253 bool isModified = textEdit->document()->isModified();
00254
00255
00256 QTextCursor cursor = textEdit->textCursor();
00257 QTextCursor oldCursor = cursor;
00258 cursor.beginEditBlock();
00259
00260 if ( placement == End )
00261 cursor.movePosition( QTextCursor::End );
00262 else if ( placement == Start )
00263 cursor.movePosition( QTextCursor::Start );
00264 textEdit->setTextCursor( cursor );
00265
00266
00267 bool hackForCursorsAtEnd = false;
00268 int oldCursorPos = -1;
00269 if ( placement == End ) {
00270
00271 if ( oldCursor.position() == textEdit->toPlainText().length() ) {
00272 hackForCursorsAtEnd = true;
00273 oldCursorPos = oldCursor.position();
00274 }
00275
00276 if ( isHtml ) {
00277 textEdit->insertHtml( QLatin1String( "<br>" ) + signature );
00278 } else {
00279 textEdit->insertPlainText( QLatin1Char( '\n' ) + signature );
00280 }
00281 } else if ( placement == Start || placement == AtCursor ) {
00282 if ( isHtml ) {
00283 textEdit->insertHtml( QLatin1String( "<br>" ) + signature + QLatin1String( "<br>" ) );
00284 } else {
00285 textEdit->insertPlainText( QLatin1Char( '\n' ) + signature + QLatin1Char( '\n' ) );
00286 }
00287 }
00288
00289 cursor.endEditBlock();
00290
00291
00292
00293
00294
00295
00296 if ( hackForCursorsAtEnd )
00297 oldCursor.setPosition( oldCursorPos );
00298
00299 textEdit->setTextCursor( oldCursor );
00300 textEdit->ensureCursorVisible();
00301
00302 textEdit->document()->setModified( isModified );
00303
00304 if ( isHtml )
00305 textEdit->enableRichTextMode();
00306 }
00307 }
00308
00309
00310
00311 QDataStream &KPIMIdentities::operator<<
00312 ( QDataStream &stream, const KPIMIdentities::Signature &sig )
00313 {
00314 return stream << static_cast<quint8>( sig.mType ) << sig.mUrl << sig.mText;
00315 }
00316
00317 QDataStream &KPIMIdentities::operator>>
00318 ( QDataStream &stream, KPIMIdentities::Signature &sig )
00319 {
00320 quint8 s;
00321 stream >> s >> sig.mUrl >> sig.mText;
00322 sig.mType = static_cast<Signature::Type>( s );
00323 return stream;
00324 }
00325
00326 bool Signature::operator== ( const Signature &other ) const
00327 {
00328 if ( mType != other.mType ) {
00329 return false;
00330 }
00331
00332 switch ( mType ) {
00333 case Inlined:
00334 return mText == other.mText;
00335 case FromFile:
00336 case FromCommand:
00337 return mUrl == other.mUrl;
00338 default:
00339 case Disabled:
00340 return true;
00341 }
00342 }
00343
00344
00345
00346 QString Signature::text() const
00347 {
00348 return mText;
00349 }
00350
00351 QString Signature::url() const
00352 {
00353 return mUrl;
00354 }
00355
00356 Signature::Type Signature::type() const
00357 {
00358 return mType;
00359 }
00360
00361
00362
00363 void Signature::setText( const QString &text )
00364 {
00365 mText = text;
00366 mType = Inlined;
00367 }
00368
00369 void Signature::setType( Type type )
00370 {
00371 mType = type;
00372 }