libkdepim Library API Documentation

email.cpp

00001 /* -*- mode: C++; c-file-style: "gnu" -*- 00002 00003 This file is part of kdepim. 00004 Copyright (c) 2004 KDEPIM developers 00005 00006 KMail is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU General Public License, version 2, as 00008 published by the Free Software Foundation. 00009 00010 KMail is distributed in the hope that it will be useful, but 00011 WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 In addition, as a special exception, the copyright holders give 00020 permission to link the code of this program with any edition of 00021 the Qt library by Trolltech AS, Norway (or with modified versions 00022 of Qt that use the same license as Qt), and distribute linked 00023 combinations including the two. You must obey the GNU General 00024 Public License in all respects for all of the code used other than 00025 Qt. If you modify this file, you may extend this exception to 00026 your version of the file, but you are not obligated to do so. If 00027 you do not wish to do so, delete this exception statement from 00028 your version. 00029 */ 00030 00031 #include "email.h" 00032 #include <kdebug.h> 00033 00034 //----------------------------------------------------------------------------- 00035 QStringList KPIM::splitEmailAddrList(const QString& aStr) 00036 { 00037 // Features: 00038 // - always ignores quoted characters 00039 // - ignores everything (including parentheses and commas) 00040 // inside quoted strings 00041 // - supports nested comments 00042 // - ignores everything (including double quotes and commas) 00043 // inside comments 00044 00045 QStringList list; 00046 00047 if (aStr.isEmpty()) 00048 return list; 00049 00050 QString addr; 00051 uint addrstart = 0; 00052 int commentlevel = 0; 00053 bool insidequote = false; 00054 00055 for (uint index=0; index<aStr.length(); index++) { 00056 // the following conversion to latin1 is o.k. because 00057 // we can safely ignore all non-latin1 characters 00058 switch (aStr[index].latin1()) { 00059 case '"' : // start or end of quoted string 00060 if (commentlevel == 0) 00061 insidequote = !insidequote; 00062 break; 00063 case '(' : // start of comment 00064 if (!insidequote) 00065 commentlevel++; 00066 break; 00067 case ')' : // end of comment 00068 if (!insidequote) { 00069 if (commentlevel > 0) 00070 commentlevel--; 00071 else { 00072 kdDebug(5300) << "Error in address splitting: Unmatched ')'" 00073 << endl; 00074 return list; 00075 } 00076 } 00077 break; 00078 case '\\' : // quoted character 00079 index++; // ignore the quoted character 00080 break; 00081 case ',' : 00082 if (!insidequote && (commentlevel == 0)) { 00083 addr = aStr.mid(addrstart, index-addrstart); 00084 if (!addr.isEmpty()) 00085 list += addr.simplifyWhiteSpace(); 00086 addrstart = index+1; 00087 } 00088 break; 00089 } 00090 } 00091 // append the last address to the list 00092 if (!insidequote && (commentlevel == 0)) { 00093 addr = aStr.mid(addrstart, aStr.length()-addrstart); 00094 if (!addr.isEmpty()) 00095 list += addr.simplifyWhiteSpace(); 00096 } 00097 else 00098 kdDebug(5300) << "Error in address splitting: " 00099 << "Unexpected end of address list" 00100 << endl; 00101 00102 return list; 00103 } 00104 00105 //----------------------------------------------------------------------------- 00106 QCString KPIM::getEmailAddr(const QString& aStr) 00107 { 00108 int a, i, j, len, found = 0; 00109 QChar c; 00110 // Find the '@' in the email address: 00111 a = aStr.find('@'); 00112 if (a<0) return aStr.latin1(); 00113 // Loop backwards until we find '<', '(', ' ', or beginning of string. 00114 for (i = a - 1; i >= 0; i--) { 00115 c = aStr[i]; 00116 if (c == '<' || c == '(' || c == ' ') found = 1; 00117 if (found) break; 00118 } 00119 // Reset found for next loop. 00120 found = 0; 00121 // Loop forwards until we find '>', ')', ' ', or end of string. 00122 for (j = a + 1; j < (int)aStr.length(); j++) { 00123 c = aStr[j]; 00124 if (c == '>' || c == ')' || c == ' ') found = 1; 00125 if (found) break; 00126 } 00127 // Calculate the length and return the result. 00128 len = j - (i + 1); 00129 return aStr.mid(i+1,len).latin1(); 00130 } 00131 00132 bool KPIM::getNameAndMail(const QString& aStr, QString& name, QString& mail) 00133 { 00134 name = QString::null; 00135 mail = QString::null; 00136 00137 const int len=aStr.length(); 00138 const char cQuotes = '"'; 00139 00140 bool bInComment, bInQuotesOutsideOfEmail; 00141 int i=0, iAd=0, iMailStart=0, iMailEnd=0; 00142 QChar c; 00143 00144 // Find the '@' of the email address 00145 // skipping all '@' inside "(...)" comments: 00146 bInComment = false; 00147 while( i < len ){ 00148 c = aStr[i]; 00149 if( !bInComment ){ 00150 if( '(' == c ){ 00151 bInComment = true; 00152 }else{ 00153 if( '@' == c ){ 00154 iAd = i; 00155 break; // found it 00156 } 00157 } 00158 }else{ 00159 if( ')' == c ){ 00160 bInComment = false; 00161 } 00162 } 00163 ++i; 00164 } 00165 00166 if( !iAd ){ 00167 // We suppose the user is typing the string manually and just 00168 // has not finished typing the mail address part. 00169 // So we take everything that's left of the '<' as name and the rest as mail 00170 for( i = 0; len > i; ++i ) { 00171 c = aStr[i]; 00172 if( '<' != c ) 00173 name.append( c ); 00174 else 00175 break; 00176 } 00177 mail = aStr.mid( i+1 ); 00178 00179 }else{ 00180 00181 // Loop backwards until we find the start of the string 00182 // or a ',' that is outside of a comment 00183 // and outside of quoted text before the leading '<'. 00184 bInComment = false; 00185 bInQuotesOutsideOfEmail = false; 00186 for( i = iAd-1; 0 <= i; --i ) { 00187 c = aStr[i]; 00188 if( bInComment ){ 00189 if( '(' == c ){ 00190 if( !name.isEmpty() ) 00191 name.prepend( ' ' ); 00192 bInComment = false; 00193 }else{ 00194 name.prepend( c ); // all comment stuff is part of the name 00195 } 00196 }else if( bInQuotesOutsideOfEmail ){ 00197 if( cQuotes == c ) 00198 bInQuotesOutsideOfEmail = false; 00199 name.prepend( c ); 00200 }else{ 00201 // found the start of this addressee ? 00202 if( ',' == c ) 00203 break; 00204 // stuff is before the leading '<' ? 00205 if( iMailStart ){ 00206 if( cQuotes == c ) 00207 bInQuotesOutsideOfEmail = true; // end of quoted text found 00208 name.prepend( c ); 00209 }else{ 00210 switch( c ){ 00211 case '<': 00212 iMailStart = i; 00213 break; 00214 case ')': 00215 if( !name.isEmpty() ) 00216 name.prepend( ' ' ); 00217 bInComment = true; 00218 break; 00219 default: 00220 if( ' ' != c ) 00221 mail.prepend( c ); 00222 } 00223 } 00224 } 00225 } 00226 00227 name = name.simplifyWhiteSpace(); 00228 mail = mail.simplifyWhiteSpace(); 00229 00230 if( mail.isEmpty() ) 00231 return false; 00232 00233 mail.append('@'); 00234 00235 // Loop forward until we find the end of the string 00236 // or a ',' that is outside of a comment 00237 // and outside of quoted text behind the trailing '>'. 00238 bInComment = false; 00239 bInQuotesOutsideOfEmail = false; 00240 for( i = iAd+1; len > i; ++i ) { 00241 c = aStr[i]; 00242 if( bInComment ){ 00243 if( ')' == c ){ 00244 if( !name.isEmpty() ) 00245 name.append( ' ' ); 00246 bInComment = false; 00247 }else{ 00248 name.append( c ); // all comment stuff is part of the name 00249 } 00250 }else if( bInQuotesOutsideOfEmail ){ 00251 if( cQuotes == c ) 00252 bInQuotesOutsideOfEmail = false; 00253 name.append( c ); 00254 }else{ 00255 // found the end of this addressee ? 00256 if( ',' == c ) 00257 break; 00258 // stuff is behind the trailing '>' ? 00259 if( iMailEnd ){ 00260 if( cQuotes == c ) 00261 bInQuotesOutsideOfEmail = true; // start of quoted text found 00262 name.append( c ); 00263 }else{ 00264 switch( c ){ 00265 case '>': 00266 iMailEnd = i; 00267 break; 00268 case '(': 00269 if( !name.isEmpty() ) 00270 name.append( ' ' ); 00271 bInComment = true; 00272 break; 00273 default: 00274 if( ' ' != c ) 00275 mail.append( c ); 00276 } 00277 } 00278 } 00279 } 00280 } 00281 00282 name = name.simplifyWhiteSpace(); 00283 mail = mail.simplifyWhiteSpace(); 00284 00285 return ! (name.isEmpty() || mail.isEmpty()); 00286 } 00287 00288 bool KPIM::compareEmail( const QString& email1, const QString& email2, 00289 bool matchName ) 00290 { 00291 QString e1Name, e1Email, e2Name, e2Email; 00292 00293 getNameAndMail( email1, e1Name, e1Email ); 00294 getNameAndMail( email2, e2Name, e2Email ); 00295 00296 return e1Email == e2Email && 00297 ( !matchName || ( e1Name == e2Name ) ); 00298 }
KDE Logo
This file is part of the documentation for libkdepim Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:18:55 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003