kmail Library API Documentation

kmidentity.cpp

00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 // kmidentity.cpp
00003 
00004 #ifdef HAVE_CONFIG_H
00005 #include <config.h>
00006 #endif
00007 
00008 #include "kmidentity.h"
00009 #include "kfileio.h"
00010 #include "kmkernel.h"
00011 
00012 #include <kdebug.h>
00013 #include <klocale.h>
00014 #include <kmessagebox.h>
00015 #include <kprocess.h>
00016 #include <kconfig.h>
00017 
00018 #include <qfileinfo.h>
00019 
00020 #include <sys/types.h>
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <errno.h>
00024 #include <assert.h>
00025 
00026 Signature::Signature()
00027   : mType( Disabled )
00028 {
00029 
00030 }
00031 
00032 Signature::Signature( const QString & text )
00033   : mText( text ),
00034     mType( Inlined )
00035 {
00036 
00037 }
00038 
00039 Signature::Signature( const QString & url, bool isExecutable )
00040   : mUrl( url ),
00041     mType( isExecutable ? FromCommand : FromFile )
00042 {
00043 }
00044 
00045 bool Signature::operator==( const Signature & other ) const {
00046   if ( mType != other.mType ) return false;
00047   switch ( mType ) {
00048   case Inlined: return mText == other.mText;
00049   case FromFile:
00050   case FromCommand: return mUrl == other.mUrl;
00051   default:
00052   case Disabled: return true;
00053   }
00054 }
00055 
00056 QString Signature::rawText( bool * ok ) const
00057 {
00058   switch ( mType ) {
00059   case Disabled:
00060     if ( ok ) *ok = true;
00061     return QString::null;
00062   case Inlined:
00063     if ( ok ) *ok = true;
00064     return mText;
00065   case FromFile:
00066     return textFromFile( ok );
00067   case FromCommand:
00068     return textFromCommand( ok );
00069   };
00070   kdFatal( 5006 ) << "Signature::type() returned unknown value!" << endl;
00071   return QString::null; // make compiler happy
00072 }
00073 
00074 QString Signature::textFromCommand( bool * ok ) const
00075 {
00076   assert( mType == FromCommand );
00077 
00078   // handle pathological cases:
00079   if ( mUrl.isEmpty() ) {
00080     if ( ok ) *ok = true;
00081     return QString::null;
00082   }
00083 
00084   // create a shell process:
00085   KProcess proc;
00086   proc.setUseShell(true);
00087   proc << mUrl;
00088 
00089   // let the kernel collect the output for us:
00090   QObject::connect( &proc, SIGNAL(receivedStdout(KProcess*,char*,int)),
00091             kmkernel, SLOT(slotCollectStdOut(KProcess*,char*,int)) );
00092 
00093   // run the process:
00094   int rc = 0;
00095   if ( !proc.start( KProcess::Block, KProcess::Stdout ) )
00096     rc = -1;
00097   else
00098     rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
00099 
00100   // get output:
00101   QByteArray output = kmkernel->getCollectedStdOut( &proc );
00102 
00103   // handle errors, if any:
00104   if ( rc != 0 ) {
00105     if ( ok ) *ok = false;
00106     QString wmsg = i18n("<qt>Failed to execute signature script<br><b>%1</b>:<br>%2</qt>")
00107       .arg( mUrl ).arg( strerror(rc) );
00108     KMessageBox::error(0, wmsg);
00109     return QString::null;
00110   }
00111 
00112   // no errors:
00113   if ( ok ) *ok = true;
00114   // ### hmm, should we allow other encodings, too?
00115   return QString::fromLocal8Bit( output.data(), output.size() );
00116 }
00117 
00118 QString Signature::textFromFile( bool * ok ) const
00119 {
00120   assert( mType == FromFile );
00121 
00122   // ### FIXME: Use KIO::NetAccess to download non-local files!
00123   if ( !KURL(mUrl).isLocalFile() && !(QFileInfo(mUrl).isRelative()
00124                     && QFileInfo(mUrl).exists()) ) {
00125     kdDebug( 5006 ) << "Signature::textFromFile: non-local URLs are unsupported" << endl;
00126     if ( ok ) *ok = false;
00127     return QString::null;
00128   }
00129   if ( ok ) *ok = true;
00130   // ### hmm, should we allow other encodings, too?
00131   return QString::fromLocal8Bit( kFileToString( mUrl, false ) );
00132 }
00133 
00134 QString Signature::withSeparator( bool * ok ) const
00135 {
00136   bool internalOK = false;
00137   QString signature = rawText( &internalOK );
00138   if ( !internalOK ) {
00139     if ( ok ) *ok = false;
00140     return QString::null;
00141   }
00142   if ( ok ) *ok = true;
00143   if ( signature.isEmpty() ) return signature; // don't add a separator in this case
00144   if ( signature.startsWith( QString::fromLatin1("-- \n") ) )
00145     // already have signature separator at start of sig:
00146     return QString::fromLatin1("\n") += signature;
00147   else if ( signature.find( QString::fromLatin1("\n-- \n") ) != -1 )
00148     // already have signature separator inside sig; don't prepend '\n'
00149     // to improve abusing signatures as templates:
00150     return signature;
00151   else
00152     // need to prepend one:
00153     return QString::fromLatin1("\n-- \n") + signature;
00154 }
00155 
00156 
00157 void Signature::setUrl( const QString & url, bool isExecutable )
00158 {
00159   mUrl = url;
00160   mType = isExecutable ? FromCommand : FromFile ;
00161 }
00162 
00163 // config keys and values:
00164 static const char sigTypeKey[] = "Signature Type";
00165 static const char sigTypeInlineValue[] = "inline";
00166 static const char sigTypeFileValue[] = "file";
00167 static const char sigTypeCommandValue[] = "command";
00168 static const char sigTypeDisabledValue[] = "disabled";
00169 static const char sigTextKey[] = "Inline Signature";
00170 static const char sigFileKey[] = "Signature File";
00171 static const char sigCommandKey[] = "Signature Command";
00172 
00173 void Signature::readConfig( const KConfigBase * config )
00174 {
00175   QString sigType = config->readEntry( sigTypeKey );
00176   if ( sigType == sigTypeInlineValue ) {
00177     mType = Inlined;
00178     mText = config->readEntry( sigTextKey );
00179   } else if ( sigType == sigTypeFileValue ) {
00180     mType = FromFile;
00181     mUrl = config->readPathEntry( sigFileKey );
00182   } else if ( sigType == sigTypeCommandValue ) {
00183     mType = FromCommand;
00184     mUrl = config->readPathEntry( sigCommandKey );
00185   } else {
00186     mType = Disabled;
00187   }
00188 }
00189 
00190 void Signature::writeConfig( KConfigBase * config ) const
00191 {
00192   switch ( mType ) {
00193   case Inlined:
00194     config->writeEntry( sigTypeKey, sigTypeInlineValue );
00195     config->writeEntry( sigTextKey, mText );
00196     break;
00197   case FromFile:
00198     config->writeEntry( sigTypeKey, sigTypeFileValue );
00199     config->writePathEntry( sigFileKey, mUrl );
00200     break;
00201   case FromCommand:
00202     config->writeEntry( sigTypeKey, sigTypeCommandValue );
00203     config->writePathEntry( sigCommandKey, mUrl );
00204     break;
00205   case Disabled:
00206     config->writeEntry( sigTypeKey, sigTypeDisabledValue );
00207   default: ;
00208   }
00209 }
00210 
00211 QDataStream & operator<<( QDataStream & stream, const Signature & sig ) {
00212   return stream << static_cast<Q_UINT8>(sig.mType)
00213         << sig.mUrl
00214         << sig.mText;
00215 }
00216 
00217 QDataStream & operator>>( QDataStream & stream, Signature & sig ) {
00218     Q_UINT8 s;
00219     stream >> s
00220            >> sig.mUrl
00221            >> sig.mText;
00222     sig.mType = static_cast<Signature::Type>(s);
00223     return stream;
00224 }
00225 
00226 KMIdentity KMIdentity::null;
00227 
00228 bool KMIdentity::isNull() const {
00229   return mIdentity.isNull() && mFullName.isNull() && mEmailAddr.isNull() &&
00230     mOrganization.isNull() && mReplyToAddr.isNull() && mBcc.isNull() &&
00231     mVCardFile.isNull() &&
00232     mPgpIdentity.isNull() && mFcc.isNull() && mDrafts.isNull() &&
00233     mTransport.isNull() && mDictionary.isNull() &&
00234     mSignature.type() == Signature::Disabled;
00235 }
00236 
00237 bool KMIdentity::operator==( const KMIdentity & other ) const {
00238     return mUoid == other.mUoid &&
00239       mIdentity == other.mIdentity && mFullName == other.mFullName &&
00240       mEmailAddr == other.mEmailAddr && mOrganization == other.mOrganization &&
00241       mReplyToAddr == other.mReplyToAddr && mBcc == other.mBcc &&
00242       mVCardFile == other.mVCardFile &&
00243       mPgpIdentity == other.mPgpIdentity && mFcc == other.mFcc &&
00244       mDrafts == other.mDrafts && mTransport == other.mTransport &&
00245       mDictionary == other.mDictionary && mSignature == other.mSignature;
00246 }
00247 
00248 KMIdentity::KMIdentity( const QString & id, const QString & fullName,
00249             const QString & emailAddr, const QString & organization,
00250             const QString & replyToAddr )
00251   : mUoid( 0 ), mIdentity( id ), mFullName( fullName ),
00252     mEmailAddr( emailAddr ), mOrganization( organization ),
00253     mReplyToAddr( replyToAddr ), mIsDefault( false )
00254 {
00255 
00256 }
00257 
00258 KMIdentity::~KMIdentity()
00259 {
00260 }
00261 
00262 
00263 void KMIdentity::readConfig( const KConfigBase * config )
00264 {
00265   mUoid = config->readUnsignedNumEntry("uoid",0);
00266 
00267   mIdentity = config->readEntry("Identity");
00268   mFullName = config->readEntry("Name");
00269   mEmailAddr = config->readEntry("Email Address");
00270   mVCardFile = config->readPathEntry("VCardFile");
00271   mOrganization = config->readEntry("Organization");
00272   mPgpIdentity = config->readEntry("Default PGP Key").local8Bit();
00273   mReplyToAddr = config->readEntry("Reply-To Address");
00274   mBcc = config->readEntry("Bcc");
00275   mFcc = config->readEntry("Fcc", "sent-mail");
00276   if( mFcc.isEmpty() )
00277     mFcc = "sent-mail";
00278   mDrafts = config->readEntry("Drafts", "drafts");
00279   if( mDrafts.isEmpty() )
00280     mDrafts = "drafts";
00281   mTransport = config->readEntry("Transport");
00282   mDictionary = config->readEntry( "Dictionary" );
00283 
00284   mSignature.readConfig( config );
00285   kdDebug(5006) << "KMIdentity::readConfig(): UOID = " << mUoid
00286         << " for identity named \"" << mIdentity << "\"" << endl;
00287 }
00288 
00289 
00290 void KMIdentity::writeConfig( KConfigBase * config ) const
00291 {
00292   config->writeEntry("uoid", mUoid);
00293 
00294   config->writeEntry("Identity", mIdentity);
00295   config->writeEntry("Name", mFullName);
00296   config->writeEntry("Organization", mOrganization);
00297   config->writeEntry("Default PGP Key", mPgpIdentity.data());
00298   config->writeEntry("Email Address", mEmailAddr);
00299   config->writeEntry("Reply-To Address", mReplyToAddr);
00300   config->writeEntry("Bcc", mBcc);
00301   config->writePathEntry("VCardFile", mVCardFile);
00302   config->writeEntry("Transport", mTransport);
00303   config->writeEntry("Fcc", mFcc);
00304   config->writeEntry("Drafts", mDrafts);
00305   config->writeEntry( "Dictionary", mDictionary );
00306 
00307   mSignature.writeConfig( config );
00308 }
00309 
00310 QDataStream & operator<<( QDataStream & stream, const KMIdentity & i ) {
00311   return stream << static_cast<Q_UINT32>(i.uoid())
00312         << i.identityName()
00313         << i.fullName()
00314         << i.organization()
00315         << i.pgpIdentity()
00316         << i.emailAddr()
00317         << i.replyToAddr()
00318         << i.bcc()
00319         << i.vCardFile()
00320         << i.transport()
00321         << i.fcc()
00322         << i.drafts()
00323         << i.mSignature
00324                 << i.dictionary();
00325 }
00326 
00327 QDataStream & operator>>( QDataStream & stream, KMIdentity & i ) {
00328 #if 1 // why doesn't it work like for Q_UINT8 above???
00329   Q_UINT32 uoid;
00330   stream >> uoid;
00331   i.mUoid = uoid;
00332   return stream
00333 #else
00334   return stream >> (Q_UINT32)i.mUoid
00335 #endif
00336         >> i.mIdentity
00337         >> i.mFullName
00338         >> i.mOrganization
00339         >> i.mPgpIdentity
00340         >> i.mEmailAddr
00341         >> i.mReplyToAddr
00342         >> i.mBcc
00343         >> i.mVCardFile
00344         >> i.mTransport
00345         >> i.mFcc
00346         >> i.mDrafts
00347         >> i.mSignature
00348                 >> i.mDictionary;
00349 }
00350 
00351 //-----------------------------------------------------------------------------
00352 bool KMIdentity::mailingAllowed() const
00353 {
00354   return !mEmailAddr.isEmpty();
00355 }
00356 
00357 
00358 void KMIdentity::setIsDefault( bool flag ) {
00359   mIsDefault = flag;
00360 }
00361 
00362 void KMIdentity::setIdentityName( const QString & name ) {
00363   mIdentity = name;
00364 }
00365 
00366 void KMIdentity::setFullName(const QString &str)
00367 {
00368   mFullName = str;
00369 }
00370 
00371 
00372 //-----------------------------------------------------------------------------
00373 void KMIdentity::setOrganization(const QString &str)
00374 {
00375   mOrganization = str;
00376 }
00377 
00378 
00379 //-----------------------------------------------------------------------------
00380 void KMIdentity::setPgpIdentity(const QCString &str)
00381 {
00382   mPgpIdentity = str;
00383 }
00384 
00385 
00386 //-----------------------------------------------------------------------------
00387 void KMIdentity::setEmailAddr(const QString &str)
00388 {
00389   mEmailAddr = str;
00390 }
00391 
00392 
00393 //-----------------------------------------------------------------------------
00394 void KMIdentity::setVCardFile(const QString &str)
00395 {
00396   mVCardFile = str;
00397 }
00398 
00399 
00400 //-----------------------------------------------------------------------------
00401 QString KMIdentity::fullEmailAddr(void) const
00402 {
00403   if (mFullName.isEmpty()) return mEmailAddr;
00404 
00405   const QString specials("()<>@,.;:[]");
00406 
00407   QString result;
00408 
00409   // add DQUOTE's if necessary:
00410   bool needsQuotes=false;
00411   for (unsigned int i=0; i < mFullName.length(); i++) {
00412     if ( specials.contains( mFullName[i] ) )
00413       needsQuotes = true;
00414     else if ( mFullName[i] == '\\' || mFullName[i] == '"' ) {
00415       needsQuotes = true;
00416       result += '\\';
00417     }
00418     result += mFullName[i];
00419   }
00420 
00421   if (needsQuotes) {
00422     result.insert(0,'"');
00423     result += '"';
00424   }
00425 
00426   result += " <" + mEmailAddr + '>';
00427 
00428   return result;
00429 }
00430 
00431 //-----------------------------------------------------------------------------
00432 void KMIdentity::setReplyToAddr(const QString& str)
00433 {
00434   mReplyToAddr = str;
00435 }
00436 
00437 
00438 //-----------------------------------------------------------------------------
00439 void KMIdentity::setSignatureFile(const QString &str)
00440 {
00441   mSignature.setUrl( str, signatureIsCommand() );
00442 }
00443 
00444 
00445 //-----------------------------------------------------------------------------
00446 void KMIdentity::setSignatureInlineText(const QString &str )
00447 {
00448   mSignature.setText( str );
00449 }
00450 
00451 
00452 //-----------------------------------------------------------------------------
00453 void KMIdentity::setTransport(const QString &str)
00454 {
00455   mTransport = str;
00456 }
00457 
00458 //-----------------------------------------------------------------------------
00459 void KMIdentity::setFcc(const QString &str)
00460 {
00461   mFcc = str;
00462 }
00463 
00464 //-----------------------------------------------------------------------------
00465 void KMIdentity::setDrafts(const QString &str)
00466 {
00467   mDrafts = str;
00468 }
00469 
00470 
00471 //-----------------------------------------------------------------------------
00472 void KMIdentity::setDictionary( const QString &str )
00473 {
00474   mDictionary = str;
00475 }
00476 
00477 
00478 //-----------------------------------------------------------------------------
00479 QString KMIdentity::signatureText( bool * ok ) const
00480 {
00481   bool internalOK = false;
00482   QString signatureText = mSignature.withSeparator( &internalOK );
00483   if ( internalOK ) {
00484     if ( ok ) *ok=true;
00485     return signatureText;
00486   }
00487 
00488   // OK, here comes the funny part. The call to
00489   // Signature::withSeparator() failed, so we should probably fix the
00490   // cause:
00491   if ( ok ) *ok = false;
00492   return QString::null;
00493 
00494 #if 0 // ### FIXME: error handling
00495   if (mSignatureFile.endsWith("|"))
00496   {
00497   }
00498   else
00499   {
00500   }
00501 #endif
00502 
00503   return QString::null;
00504 }
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:37:29 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003