• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

KCalCore Library

person.cpp
Go to the documentation of this file.
00001 /*
00002   This file is part of the kcalcore library.
00003 
00004   Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00005   Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006   Copyright (C) 2010 Casey Link <unnamedrambler@gmail.com>
00007   Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Library General Public
00011   License as published by the Free Software Foundation; either
00012   version 2 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Library General Public License for more details.
00018 
00019   You should have received a copy of the GNU Library General Public License
00020   along with this library; see the file COPYING.LIB.  If not, write to
00021   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00022   Boston, MA 02110-1301, USA.
00023 */
00036 #include "person.h"
00037 #include <QtCore/QRegExp>
00038 
00039 using namespace KCalCore;
00040 
00045 //@cond PRIVATE
00046 class KCalCore::Person::Private
00047 {
00048   public:
00049     Private() : mCount( 0 ) {}
00050     QString mName;   // person name
00051     QString mEmail;  // person email address
00052     int mCount;      // person reference count
00053 };
00054 //@endcond
00055 
00056 Person::Person() : d( new KCalCore::Person::Private )
00057 {
00058 }
00059 
00060 Person::Person( const QString &name, const QString &email )
00061   : d( new KCalCore::Person::Private )
00062 {
00063   d->mName = name;
00064   d->mEmail = email;
00065 }
00066 
00067 Person::Person( const Person &person )
00068   : d( new KCalCore::Person::Private( *person.d ) )
00069 {
00070 }
00071 
00072 Person::~Person()
00073 {
00074   delete d;
00075 }
00076 
00077 bool KCalCore::Person::operator==( const Person &person ) const
00078 {
00079   return
00080     d->mName == person.d->mName &&
00081     d->mEmail == person.d->mEmail;
00082 }
00083 
00084 bool KCalCore::Person::operator!=( const Person &person ) const
00085 {
00086   return !( *this == person );
00087 }
00088 
00089 Person &KCalCore::Person::operator=( const Person &person )
00090 {
00091   // check for self assignment
00092   if ( &person == this ) {
00093     return *this;
00094   }
00095 
00096   *d = *person.d;
00097   return *this;
00098 }
00099 
00100 QString Person::fullName() const
00101 {
00102   if ( d->mName.isEmpty() ) {
00103     return d->mEmail;
00104   } else {
00105     if ( d->mEmail.isEmpty() ) {
00106       return d->mName;
00107     } else {
00108       // Taken from KABC::Addressee::fullEmail
00109       QString name = d->mName;
00110       QRegExp needQuotes( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" );
00111       bool weNeedToQuote = name.indexOf( needQuotes ) != -1;
00112       if ( weNeedToQuote ) {
00113         if ( name[0] != '"' ) {
00114           name.prepend( '"' );
00115         }
00116         if ( name[ name.length()-1 ] != '"' ) {
00117           name.append( '"' );
00118         }
00119       }
00120       return name + " <" + d->mEmail + '>';
00121     }
00122   }
00123 }
00124 
00125 QString Person::name() const
00126 {
00127   return d->mName;
00128 }
00129 
00130 QString Person::email() const
00131 {
00132   return d->mEmail;
00133 }
00134 
00135 bool Person::isEmpty() const
00136 {
00137   return d->mEmail.isEmpty() && d->mName.isEmpty();
00138 }
00139 
00140 void Person::setName( const QString &name )
00141 {
00142   d->mName = name;
00143 }
00144 
00145 void Person::setEmail( const QString &email )
00146 {
00147   if ( email.startsWith( QLatin1String( "mailto:" ), Qt::CaseInsensitive ) ) {
00148     d->mEmail = email.mid( 7 );
00149   } else {
00150     d->mEmail = email;
00151   }
00152 }
00153 
00155 bool Person::isValidEmail( const QString &email )
00156 {
00157   int pos = email.lastIndexOf( "@" );
00158   return ( pos > 0 ) && ( email.lastIndexOf( "." ) > pos ) && ( ( email.length() - pos ) > 4 );
00159 }
00160 
00161 void Person::setCount( int count )
00162 {
00163   d->mCount = count;
00164 }
00165 
00166 int Person::count() const
00167 {
00168   return d->mCount;
00169 }
00170 
00171 uint qHash( const KCalCore::Person &key )
00172 {
00173   return qHash( key.fullName() );
00174 }
00175 
00176 QDataStream &KCalCore::operator<<( QDataStream &stream, const KCalCore::Person::Ptr &person )
00177 {
00178   return stream << person->d->mName
00179                 << person->d->mEmail
00180                 << person->d->mCount;
00181 }
00182 
00183 QDataStream &KCalCore::operator>>( QDataStream &stream, Person::Ptr &person )
00184 {
00185   QString name, email;
00186   int count;
00187 
00188   stream >> name >> email >> count;
00189 
00190   Person::Ptr person_tmp( new Person( name, email ) );
00191   person_tmp->setCount( count );
00192   person.swap( person_tmp );
00193   return stream;
00194 }
00195 
00196 // The following function was lifted directly from KPIMUtils
00197 // in order to eliminate the dependency on that library.
00198 // Any changes made here should be ported there, and vice versa.
00199 static bool extractEmailAddressAndName( const QString &aStr, QString &mail, QString &name )
00200 {
00201   name.clear();
00202   mail.clear();
00203 
00204   const int len = aStr.length();
00205   const char cQuotes = '"';
00206 
00207   bool bInComment = false;
00208   bool bInQuotesOutsideOfEmail = false;
00209   int i=0, iAd=0, iMailStart=0, iMailEnd=0;
00210   QChar c;
00211   unsigned int commentstack = 0;
00212 
00213   // Find the '@' of the email address
00214   // skipping all '@' inside "(...)" comments:
00215   while ( i < len ) {
00216     c = aStr[i];
00217     if ( '(' == c ) {
00218       commentstack++;
00219     }
00220     if ( ')' == c ) {
00221       commentstack--;
00222     }
00223     bInComment = commentstack != 0;
00224     if ( '"' == c && !bInComment ) {
00225       bInQuotesOutsideOfEmail = !bInQuotesOutsideOfEmail;
00226     }
00227 
00228     if( !bInComment && !bInQuotesOutsideOfEmail ) {
00229       if ( '@' == c ) {
00230         iAd = i;
00231         break; // found it
00232       }
00233     }
00234     ++i;
00235   }
00236 
00237   if ( !iAd ) {
00238     // We suppose the user is typing the string manually and just
00239     // has not finished typing the mail address part.
00240     // So we take everything that's left of the '<' as name and the rest as mail
00241     for ( i = 0; len > i; ++i ) {
00242       c = aStr[i];
00243       if ( '<' != c ) {
00244         name.append( c );
00245       } else {
00246         break;
00247       }
00248     }
00249     mail = aStr.mid( i + 1 );
00250     if ( mail.endsWith( '>' ) ) {
00251       mail.truncate( mail.length() - 1 );
00252     }
00253 
00254   } else {
00255     // Loop backwards until we find the start of the string
00256     // or a ',' that is outside of a comment
00257     //          and outside of quoted text before the leading '<'.
00258     bInComment = false;
00259     bInQuotesOutsideOfEmail = false;
00260     for ( i = iAd-1; 0 <= i; --i ) {
00261       c = aStr[i];
00262       if ( bInComment ) {
00263         if ( '(' == c ) {
00264           if ( !name.isEmpty() ) {
00265             name.prepend( ' ' );
00266           }
00267           bInComment = false;
00268         } else {
00269           name.prepend( c ); // all comment stuff is part of the name
00270         }
00271       } else if ( bInQuotesOutsideOfEmail ) {
00272         if ( cQuotes == c ) {
00273           bInQuotesOutsideOfEmail = false;
00274         } else if ( c != '\\' ) {
00275           name.prepend( c );
00276         }
00277       } else {
00278         // found the start of this addressee ?
00279         if ( ',' == c ) {
00280           break;
00281         }
00282         // stuff is before the leading '<' ?
00283         if ( iMailStart ) {
00284           if ( cQuotes == c ) {
00285             bInQuotesOutsideOfEmail = true; // end of quoted text found
00286           } else {
00287             name.prepend( c );
00288           }
00289         } else {
00290           switch ( c.toLatin1() ) {
00291           case '<':
00292             iMailStart = i;
00293             break;
00294           case ')':
00295             if ( !name.isEmpty() ) {
00296               name.prepend( ' ' );
00297             }
00298             bInComment = true;
00299             break;
00300           default:
00301             if ( ' ' != c ) {
00302               mail.prepend( c );
00303             }
00304           }
00305         }
00306       }
00307     }
00308 
00309     name = name.simplified();
00310     mail = mail.simplified();
00311 
00312     if ( mail.isEmpty() ) {
00313       return false;
00314     }
00315 
00316     mail.append( '@' );
00317 
00318     // Loop forward until we find the end of the string
00319     // or a ',' that is outside of a comment
00320     //          and outside of quoted text behind the trailing '>'.
00321     bInComment = false;
00322     bInQuotesOutsideOfEmail = false;
00323     int parenthesesNesting = 0;
00324     for ( i = iAd+1; len > i; ++i ) {
00325       c = aStr[i];
00326       if ( bInComment ) {
00327         if ( ')' == c ) {
00328           if ( --parenthesesNesting == 0 ) {
00329             bInComment = false;
00330             if ( !name.isEmpty() ) {
00331               name.append( ' ' );
00332             }
00333           } else {
00334             // nested ")", add it
00335             name.append( ')' ); // name can't be empty here
00336           }
00337         } else {
00338           if ( '(' == c ) {
00339             // nested "("
00340             ++parenthesesNesting;
00341           }
00342           name.append( c ); // all comment stuff is part of the name
00343         }
00344       } else if ( bInQuotesOutsideOfEmail ) {
00345         if ( cQuotes == c ) {
00346           bInQuotesOutsideOfEmail = false;
00347         } else if ( c != '\\' ) {
00348           name.append( c );
00349         }
00350       } else {
00351         // found the end of this addressee ?
00352         if ( ',' == c ) {
00353           break;
00354         }
00355         // stuff is behind the trailing '>' ?
00356         if ( iMailEnd ){
00357           if ( cQuotes == c ) {
00358             bInQuotesOutsideOfEmail = true; // start of quoted text found
00359           } else {
00360             name.append( c );
00361           }
00362         } else {
00363           switch ( c.toLatin1() ) {
00364           case '>':
00365             iMailEnd = i;
00366             break;
00367           case '(':
00368             if ( !name.isEmpty() ) {
00369               name.append( ' ' );
00370             }
00371             if ( ++parenthesesNesting > 0 ) {
00372               bInComment = true;
00373             }
00374             break;
00375           default:
00376             if ( ' ' != c ) {
00377               mail.append( c );
00378             }
00379           }
00380         }
00381       }
00382     }
00383   }
00384 
00385   name = name.simplified();
00386   mail = mail.simplified();
00387 
00388   return ! ( name.isEmpty() || mail.isEmpty() );
00389 }
00390 
00392 Person::Ptr Person::fromFullName( const QString &fullName )
00393 {
00394   QString email, name;
00395   extractEmailAddressAndName( fullName, email, name );
00396   return Person::Ptr( new Person( name, email ) );
00397 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:07:48 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCalCore Library

Skip menu "KCalCore Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepimlibs-4.8.5 API Reference

Skip menu "kdepimlibs-4.8.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal