kpimidentities
identity.cpp
00001 /* 00002 Copyright (c) 2002-2004 Marc Mutz <mutz@kde.org> 00003 Copyright (c) 2007 Tom Albers <tomalbers@kde.nl> 00004 00005 This library is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU Library General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or (at your 00008 option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, but WITHOUT 00011 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to the 00017 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00018 02110-1301, USA. 00019 */ 00020 00021 #include "identity.h" 00022 #include "signature.h" 00023 00024 #include <kdeversion.h> 00025 #include <sonnet/globals.h> 00026 #include <kdebug.h> 00027 #include <klocale.h> 00028 #include <kmessagebox.h> 00029 #include <kconfiggroup.h> 00030 #include <kurl.h> 00031 #include <kprocess.h> 00032 #include <kpimutils/kfileio.h> 00033 #include <kpimutils/email.h> 00034 00035 #include <QFileInfo> 00036 #include <QMimeData> 00037 #include <QByteArray> 00038 00039 #include <sys/types.h> 00040 #include <stdlib.h> 00041 #include <stdio.h> 00042 #include <errno.h> 00043 #include <assert.h> 00044 00045 using namespace KPIMIdentities; 00046 00047 // TODO: should use a kstaticdeleter? 00048 static Identity *identityNull = 0; 00049 00050 Identity::Identity( const QString &id, const QString &fullName, 00051 const QString &emailAddr, const QString &organization, 00052 const QString &replyToAddr ) 00053 : mIsDefault( false ) 00054 { 00055 setProperty( s_uoid, 0 ); 00056 setProperty( s_identity, id ); 00057 setProperty( s_name, fullName ); 00058 setProperty( s_email, emailAddr ); 00059 setProperty( s_organization, organization ); 00060 setProperty( s_replyto, replyToAddr ); 00061 setDictionary( Sonnet::defaultLanguageName() ); 00062 } 00063 00064 Identity::~Identity() 00065 {} 00066 00067 const Identity &Identity::null() 00068 { 00069 if ( !identityNull ) { 00070 identityNull = new Identity; 00071 } 00072 return *identityNull; 00073 } 00074 00075 bool Identity::isNull() const 00076 { 00077 bool empty = true; 00078 QHash<QString, QVariant>::const_iterator i = mPropertiesMap.constBegin(); 00079 while ( i != mPropertiesMap.constEnd() ) { 00080 00081 // Take into account that the dictionary for a null identity is not empty 00082 if ( i.key() == s_dict && dictionary() == Sonnet::defaultLanguageName() ) { 00083 ++i; 00084 continue; 00085 } 00086 00087 // The uoid is 0 by default, so ignore this 00088 if ( !( i.key() == s_uoid && i.value().toUInt() == 0 ) ) { 00089 if ( !i.value().isNull() || 00090 ( i.value().type() == QVariant::String && !i.value().toString().isEmpty() ) ) { 00091 empty = false; 00092 } 00093 } 00094 ++i; 00095 } 00096 return empty; 00097 } 00098 00099 void Identity::readConfig( const KConfigGroup &config ) 00100 { 00101 // get all keys and convert them to our QHash. 00102 QMap<QString,QString> entries = config.entryMap(); 00103 QMap<QString,QString>::const_iterator i = entries.constBegin(); 00104 while ( i != entries.constEnd() ) { 00105 if ( i.key() == s_emailAliases ) { 00106 // HACK: Read s_emailAliases as a stringlist 00107 mPropertiesMap.insert( i.key(), config.readEntry( i.key(), QStringList() ) ); 00108 } else { 00109 mPropertiesMap.insert( i.key(), config.readEntry( i.key() ) ); 00110 } 00111 ++i; 00112 } 00113 mSignature.readConfig( config ); 00114 } 00115 00116 void Identity::writeConfig( KConfigGroup &config ) const 00117 { 00118 QHash<QString, QVariant>::const_iterator i = mPropertiesMap.constBegin(); 00119 while ( i != mPropertiesMap.constEnd() ) { 00120 config.writeEntry( i.key(), i.value() ); 00121 kDebug( 5325 ) << "Store:" << i.key() << ":" << i.value(); 00122 ++i; 00123 } 00124 mSignature.writeConfig( config ); 00125 } 00126 00127 bool Identity::mailingAllowed() const 00128 { 00129 return !property( s_email ).toString().isEmpty(); 00130 } 00131 00132 QString Identity::mimeDataType() 00133 { 00134 return "application/x-kmail-identity-drag"; 00135 } 00136 00137 bool Identity::canDecode( const QMimeData*md ) 00138 { 00139 return md->hasFormat( mimeDataType() ); 00140 } 00141 00142 void Identity::populateMimeData( QMimeData*md ) 00143 { 00144 QByteArray a; 00145 { 00146 QDataStream s( &a, QIODevice::WriteOnly ); 00147 s << this; 00148 } 00149 md->setData( mimeDataType(), a ); 00150 } 00151 00152 Identity Identity::fromMimeData( const QMimeData*md ) 00153 { 00154 Identity i; 00155 if ( canDecode( md ) ) { 00156 QByteArray ba = md->data( mimeDataType() ); 00157 QDataStream s( &ba, QIODevice::ReadOnly ); 00158 s >> i; 00159 } 00160 return i; 00161 } 00162 00163 // ------------------ Operators --------------------------// 00164 00165 QDataStream &KPIMIdentities::operator<< 00166 ( QDataStream &stream, const KPIMIdentities::Identity &i ) 00167 { 00168 return stream << static_cast<quint32>( i.uoid() ) 00169 << i.identityName() 00170 << i.fullName() 00171 << i.organization() 00172 << i.pgpSigningKey() 00173 << i.pgpEncryptionKey() 00174 << i.smimeSigningKey() 00175 << i.smimeEncryptionKey() 00176 << i.primaryEmailAddress() 00177 << i.emailAliases() 00178 << i.replyToAddr() 00179 << i.bcc() 00180 << i.vCardFile() 00181 << i.transport() 00182 << i.fcc() 00183 << i.drafts() 00184 << i.templates() 00185 << i.mPropertiesMap[s_signature] 00186 << i.dictionary() 00187 << i.xface() 00188 << i.preferredCryptoMessageFormat(); 00189 } 00190 00191 QDataStream &KPIMIdentities::operator>> 00192 ( QDataStream &stream, KPIMIdentities::Identity &i ) 00193 { 00194 quint32 uoid; 00195 QString format; 00196 stream 00197 >> uoid 00198 >> i.mPropertiesMap[s_identity] 00199 >> i.mPropertiesMap[s_name] 00200 >> i.mPropertiesMap[s_organization] 00201 >> i.mPropertiesMap[s_pgps] 00202 >> i.mPropertiesMap[s_pgpe] 00203 >> i.mPropertiesMap[s_smimes] 00204 >> i.mPropertiesMap[s_smimee] 00205 >> i.mPropertiesMap[s_email] 00206 >> i.mPropertiesMap[s_emailAliases] 00207 >> i.mPropertiesMap[s_replyto] 00208 >> i.mPropertiesMap[s_bcc] 00209 >> i.mPropertiesMap[s_vcard] 00210 >> i.mPropertiesMap[s_transport] 00211 >> i.mPropertiesMap[s_fcc] 00212 >> i.mPropertiesMap[s_drafts] 00213 >> i.mPropertiesMap[s_templates] 00214 >> i.mPropertiesMap[s_signature] 00215 >> i.mPropertiesMap[s_dict] 00216 >> i.mPropertiesMap[s_xface] 00217 >> i.mPropertiesMap[s_prefcrypt]; 00218 i.setProperty( s_uoid, uoid ); 00219 return stream; 00220 } 00221 00222 bool Identity::operator< ( const Identity &other ) const 00223 { 00224 if ( isDefault() ) { 00225 return true; 00226 } 00227 if ( other.isDefault() ) { 00228 return false; 00229 } 00230 return identityName() < other.identityName(); 00231 } 00232 00233 bool Identity::operator> ( const Identity &other ) const 00234 { 00235 if ( isDefault() ) { 00236 return false; 00237 } 00238 if ( other.isDefault() ) { 00239 return true; 00240 } 00241 return identityName() > other.identityName(); 00242 } 00243 00244 bool Identity::operator<= ( const Identity &other ) const 00245 { 00246 return !operator> ( other ); 00247 } 00248 00249 bool Identity::operator>= ( const Identity &other ) const 00250 { 00251 return !operator< ( other ); 00252 } 00253 00254 bool Identity::operator== ( const Identity &other ) const 00255 { 00256 return mPropertiesMap == other.mPropertiesMap && 00257 mSignature == other.mSignature; 00258 } 00259 00260 bool Identity::operator!= ( const Identity &other ) const 00261 { 00262 return !operator== ( other ); 00263 } 00264 00265 // --------------------- Getters -----------------------------// 00266 00267 QVariant Identity::property( const QString &key ) const 00268 { 00269 return mPropertiesMap.value( key ); 00270 } 00271 00272 QString Identity::fullEmailAddr( void ) const 00273 { 00274 const QString name = mPropertiesMap.value( s_name ).toString(); 00275 const QString mail = mPropertiesMap.value( s_email ).toString(); 00276 00277 if ( name.isEmpty() ) { 00278 return mail; 00279 } 00280 00281 const QString specials( "()<>@,.;:[]" ); 00282 00283 QString result; 00284 00285 // add DQUOTE's if necessary: 00286 bool needsQuotes=false; 00287 for ( int i=0; i < name.length(); i++ ) { 00288 if ( specials.contains( name[i] ) ) { 00289 needsQuotes = true; 00290 } else if ( name[i] == '\\' || name[i] == '"' ) { 00291 needsQuotes = true; 00292 result += '\\'; 00293 } 00294 result += name[i]; 00295 } 00296 00297 if ( needsQuotes ) { 00298 result.insert( 0,'"' ); 00299 result += '"'; 00300 } 00301 00302 result += " <" + mail + '>'; 00303 00304 return result; 00305 } 00306 00307 QString Identity::identityName() const 00308 { 00309 return property( QLatin1String( s_identity ) ).toString(); 00310 } 00311 00312 QString Identity::signatureText( bool *ok ) const 00313 { 00314 return mSignature.withSeparator( ok ); 00315 } 00316 00317 bool Identity::signatureIsInlinedHtml() const 00318 { 00319 return mSignature.isInlinedHtml(); 00320 } 00321 00322 bool Identity::isDefault() const 00323 { 00324 return mIsDefault; 00325 } 00326 00327 uint Identity::uoid() const 00328 { 00329 return property( QLatin1String( s_uoid ) ).toInt(); 00330 } 00331 00332 QString Identity::fullName() const 00333 { 00334 return property( QLatin1String( s_name ) ).toString(); 00335 } 00336 00337 QString Identity::organization() const 00338 { 00339 return property( QLatin1String( s_organization ) ).toString(); 00340 } 00341 00342 QByteArray Identity::pgpEncryptionKey() const 00343 { 00344 return property( QLatin1String( s_pgpe ) ).toByteArray(); 00345 } 00346 00347 QByteArray Identity::pgpSigningKey() const 00348 { 00349 return property( QLatin1String( s_pgps ) ).toByteArray(); 00350 } 00351 00352 QByteArray Identity::smimeEncryptionKey() const 00353 { 00354 return property( QLatin1String( s_smimee ) ).toByteArray(); 00355 } 00356 00357 QByteArray Identity::smimeSigningKey() const 00358 { 00359 return property( QLatin1String( s_smimes ) ).toByteArray(); 00360 } 00361 00362 QString Identity::preferredCryptoMessageFormat() const 00363 { 00364 return property( QLatin1String( s_prefcrypt ) ).toString(); 00365 } 00366 00367 QString Identity::emailAddr() const 00368 { 00369 return primaryEmailAddress(); 00370 } 00371 00372 QString Identity::primaryEmailAddress() const 00373 { 00374 return property( QLatin1String( s_email ) ).toString(); 00375 } 00376 00377 const QStringList Identity::emailAliases() const 00378 { 00379 return property( QLatin1String( s_emailAliases ) ).toStringList(); 00380 } 00381 00382 QString Identity::vCardFile() const 00383 { 00384 return property( QLatin1String( s_vcard ) ).toString(); 00385 } 00386 00387 QString Identity::replyToAddr() const 00388 { 00389 return property( QLatin1String( s_replyto ) ).toString(); 00390 } 00391 00392 QString Identity::bcc() const 00393 { 00394 return property( QLatin1String( s_bcc ) ).toString(); 00395 } 00396 00397 Signature &Identity::signature() 00398 { 00399 return mSignature; 00400 } 00401 00402 bool Identity::isXFaceEnabled() const 00403 { 00404 return property( QLatin1String( s_xfaceenabled ) ).toBool(); 00405 } 00406 00407 QString Identity::xface() const 00408 { 00409 return property( QLatin1String( s_xface ) ).toString(); 00410 } 00411 00412 QString Identity::dictionary() const 00413 { 00414 return property( QLatin1String( s_dict ) ).toString(); 00415 } 00416 00417 QString Identity::templates() const 00418 { 00419 return property( QLatin1String( s_templates ) ).toString(); 00420 } 00421 00422 QString Identity::drafts() const 00423 { 00424 return property( QLatin1String( s_drafts ) ).toString(); 00425 } 00426 00427 QString Identity::fcc() const 00428 { 00429 return property( QLatin1String( s_fcc ) ).toString(); 00430 } 00431 00432 QString Identity::transport() const 00433 { 00434 return property( QLatin1String( s_transport ) ).toString(); 00435 } 00436 00437 bool Identity::signatureIsCommand() const 00438 { 00439 return mSignature.type() == Signature::FromCommand; 00440 } 00441 00442 bool Identity::signatureIsPlainFile() const 00443 { 00444 return mSignature.type() == Signature::FromFile; 00445 } 00446 00447 bool Identity::signatureIsInline() const 00448 { 00449 return mSignature.type() == Signature::Inlined; 00450 } 00451 00452 bool Identity::useSignatureFile() const 00453 { 00454 return signatureIsPlainFile() || signatureIsCommand(); 00455 } 00456 00457 QString Identity::signatureInlineText() const 00458 { 00459 return mSignature.text(); 00460 } 00461 00462 QString Identity::signatureFile() const 00463 { 00464 return mSignature.url(); 00465 } 00466 00467 // --------------------- Setters -----------------------------// 00468 00469 void Identity::setProperty( const QString &key, const QVariant &value ) 00470 { 00471 if ( value.isNull() || 00472 ( value.type() == QVariant::String && value.toString().isEmpty() ) ) { 00473 mPropertiesMap.remove( key ); 00474 } else { 00475 mPropertiesMap.insert( key, value ); 00476 } 00477 } 00478 00479 void Identity::setUoid( uint aUoid ) 00480 { 00481 setProperty( s_uoid, aUoid ); 00482 } 00483 00484 void Identity::setIdentityName( const QString &name ) 00485 { 00486 setProperty( s_identity, name ); 00487 } 00488 00489 void Identity::setFullName( const QString &str ) 00490 { 00491 setProperty( s_name, str ); 00492 } 00493 00494 void Identity::setOrganization( const QString &str ) 00495 { 00496 setProperty( s_organization, str ); 00497 } 00498 00499 void Identity::setPGPSigningKey( const QByteArray &str ) 00500 { 00501 setProperty( s_pgps, QString( str ) ); 00502 } 00503 00504 void Identity::setPGPEncryptionKey( const QByteArray &str ) 00505 { 00506 setProperty( s_pgpe, QString( str ) ); 00507 } 00508 00509 void Identity::setSMIMESigningKey( const QByteArray &str ) 00510 { 00511 setProperty( s_smimes, QString( str ) ); 00512 } 00513 00514 void Identity::setSMIMEEncryptionKey( const QByteArray &str ) 00515 { 00516 setProperty( s_smimee, QString( str ) ); 00517 } 00518 00519 void Identity::setEmailAddr( const QString &str ) 00520 { 00521 setPrimaryEmailAddress( str ); 00522 } 00523 00524 void Identity::setPrimaryEmailAddress( const QString & email ) 00525 { 00526 setProperty( s_email, email ); 00527 } 00528 00529 void Identity::setEmailAliases( const QStringList & aliases ) 00530 { 00531 setProperty( s_emailAliases, aliases ); 00532 } 00533 00534 void Identity::setVCardFile( const QString &str ) 00535 { 00536 setProperty( s_vcard, str ); 00537 } 00538 00539 void Identity::setReplyToAddr( const QString&str ) 00540 { 00541 setProperty( s_replyto, str ); 00542 } 00543 00544 void Identity::setSignatureFile( const QString &str ) 00545 { 00546 mSignature.setUrl( str, signatureIsCommand() ); 00547 } 00548 00549 void Identity::setSignatureInlineText( const QString &str ) 00550 { 00551 mSignature.setText( str ); 00552 } 00553 00554 void Identity::setTransport( const QString &str ) 00555 { 00556 setProperty( s_transport, str ); 00557 } 00558 00559 void Identity::setFcc( const QString &str ) 00560 { 00561 setProperty( s_fcc, str ); 00562 } 00563 00564 void Identity::setDrafts( const QString &str ) 00565 { 00566 setProperty( s_drafts, str ); 00567 } 00568 00569 void Identity::setTemplates( const QString &str ) 00570 { 00571 setProperty( s_templates, str ); 00572 } 00573 00574 void Identity::setDictionary( const QString &str ) 00575 { 00576 setProperty( s_dict, str ); 00577 } 00578 00579 void Identity::setBcc( const QString &str ) 00580 { 00581 setProperty( s_bcc, str ); 00582 } 00583 00584 void Identity::setIsDefault( bool flag ) 00585 { 00586 mIsDefault = flag; 00587 } 00588 00589 void Identity::setPreferredCryptoMessageFormat( const QString &str ) 00590 { 00591 setProperty( s_prefcrypt, str ); 00592 } 00593 00594 void Identity::setXFace( const QString &str ) 00595 { 00596 QString strNew = str; 00597 strNew.remove( ' ' ); 00598 strNew.remove( '\n' ); 00599 strNew.remove( '\r' ); 00600 setProperty( s_xface, strNew ); 00601 } 00602 00603 void Identity::setXFaceEnabled( const bool on ) 00604 { 00605 setProperty( s_xfaceenabled, on ); 00606 } 00607 00608 void Identity::setSignature( const Signature &sig ) 00609 { 00610 mSignature = sig; 00611 } 00612 00613 bool Identity::matchesEmailAddress( const QString & addr ) const 00614 { 00615 const QString addrSpec = KPIMUtils::extractEmailAddress( addr ).toLower(); 00616 if ( addrSpec == primaryEmailAddress().toLower() ) 00617 return true; 00618 00619 foreach ( const QString &alias, emailAliases() ) { 00620 if ( alias.toLower() == addrSpec ) 00621 return true; 00622 } 00623 00624 return false; 00625 }