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
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.