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

KCalCore Library

  • kcalcore
person.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore library.
3 
4  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6  Copyright (C) 2010 Casey Link <unnamedrambler@gmail.com>
7  Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Library General Public
11  License as published by the Free Software Foundation; either
12  version 2 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Library General Public License for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with this library; see the file COPYING.LIB. If not, write to
21  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  Boston, MA 02110-1301, USA.
23 */
36 #include "person.h"
37 #include <QtCore/QRegExp>
38 #include <QtCore/QDataStream>
39 
40 using namespace KCalCore;
41 
46 //@cond PRIVATE
47 class KCalCore::Person::Private
48 {
49 public:
50  Private() : mCount(0) {}
51  QString mName; // person name
52  QString mEmail; // person email address
53  int mCount; // person reference count
54 };
55 //@endcond
56 
57 Person::Person() : d(new KCalCore::Person::Private)
58 {
59 }
60 
61 Person::Person(const QString &name, const QString &email)
62  : d(new KCalCore::Person::Private)
63 {
64  d->mName = name;
65  d->mEmail = email;
66 }
67 
68 Person::Person(const Person &person)
69  : d(new KCalCore::Person::Private(*person.d))
70 {
71 }
72 
73 Person::~Person()
74 {
75  delete d;
76 }
77 
78 bool KCalCore::Person::operator==(const Person &person) const
79 {
80  return
81  d->mName == person.d->mName &&
82  d->mEmail == person.d->mEmail;
83 }
84 
85 bool KCalCore::Person::operator!=(const Person &person) const
86 {
87  return !(*this == person);
88 }
89 
90 Person &KCalCore::Person::operator=(const Person &person)
91 {
92  // check for self assignment
93  if (&person == this) {
94  return *this;
95  }
96 
97  *d = *person.d;
98  return *this;
99 }
100 
101 QString Person::fullName() const
102 {
103  if (d->mName.isEmpty()) {
104  return d->mEmail;
105  } else {
106  if (d->mEmail.isEmpty()) {
107  return d->mName;
108  } else {
109  // Taken from KABC::Addressee::fullEmail
110  QString name = d->mName;
111  QRegExp needQuotes("[^ 0-9A-Za-z\\x0080-\\xFFFF]");
112  bool weNeedToQuote = name.indexOf(needQuotes) != -1;
113  if (weNeedToQuote) {
114  if (name[0] != '"') {
115  name.prepend('"');
116  }
117  if (name[ name.length()-1 ] != '"') {
118  name.append('"');
119  }
120  }
121  return name + " <" + d->mEmail + '>';
122  }
123  }
124 }
125 
126 QString Person::name() const
127 {
128  return d->mName;
129 }
130 
131 QString Person::email() const
132 {
133  return d->mEmail;
134 }
135 
136 bool Person::isEmpty() const
137 {
138  return d->mEmail.isEmpty() && d->mName.isEmpty();
139 }
140 
141 void Person::setName(const QString &name)
142 {
143  d->mName = name;
144 }
145 
146 void Person::setEmail(const QString &email)
147 {
148  if (email.startsWith(QLatin1String("mailto:"), Qt::CaseInsensitive)) {
149  d->mEmail = email.mid(7);
150  } else {
151  d->mEmail = email;
152  }
153 }
154 
155 bool Person::isValidEmail(const QString &email)
156 {
157  int pos = email.lastIndexOf("@");
158  return (pos > 0) && (email.lastIndexOf(".") > pos) && ((email.length() - pos) > 4);
159 }
160 
161 void Person::setCount(int count)
162 {
163  d->mCount = count;
164 }
165 
166 int Person::count() const
167 {
168  return d->mCount;
169 }
170 
171 uint qHash(const KCalCore::Person &key)
172 {
173  return qHash(key.fullName());
174 }
175 
176 QDataStream &KCalCore::operator<<(QDataStream &stream, const KCalCore::Person::Ptr &person)
177 {
178  return stream << person->d->mName
179  << person->d->mEmail
180  << person->d->mCount;
181 }
182 
183 QDataStream &KCalCore::operator>>(QDataStream &stream, Person::Ptr &person)
184 {
185  QString name, email;
186  int count;
187 
188  stream >> name >> email >> count;
189 
190  Person::Ptr person_tmp(new Person(name, email));
191  person_tmp->setCount(count);
192  person.swap(person_tmp);
193  return stream;
194 }
195 
196 // The following function was lifted directly from KPIMUtils
197 // in order to eliminate the dependency on that library.
198 // Any changes made here should be ported there, and vice versa.
199 static bool extractEmailAddressAndName(const QString &aStr, QString &mail, QString &name)
200 {
201  name.clear();
202  mail.clear();
203 
204  const int len = aStr.length();
205  const char cQuotes = '"';
206 
207  bool bInComment = false;
208  bool bInQuotesOutsideOfEmail = false;
209  int i=0, iAd=0, iMailStart=0, iMailEnd=0;
210  QChar c;
211  unsigned int commentstack = 0;
212 
213  // Find the '@' of the email address
214  // skipping all '@' inside "(...)" comments:
215  while (i < len) {
216  c = aStr[i];
217  if ('(' == c) {
218  commentstack++;
219  }
220  if (')' == c) {
221  commentstack--;
222  }
223  bInComment = commentstack != 0;
224  if ('"' == c && !bInComment) {
225  bInQuotesOutsideOfEmail = !bInQuotesOutsideOfEmail;
226  }
227 
228  if (!bInComment && !bInQuotesOutsideOfEmail) {
229  if ('@' == c) {
230  iAd = i;
231  break; // found it
232  }
233  }
234  ++i;
235  }
236 
237  if (!iAd) {
238  // We suppose the user is typing the string manually and just
239  // has not finished typing the mail address part.
240  // So we take everything that's left of the '<' as name and the rest as mail
241  for (i = 0; len > i; ++i) {
242  c = aStr[i];
243  if ('<' != c) {
244  name.append(c);
245  } else {
246  break;
247  }
248  }
249  mail = aStr.mid(i + 1);
250  if (mail.endsWith('>')) {
251  mail.truncate(mail.length() - 1);
252  }
253 
254  } else {
255  // Loop backwards until we find the start of the string
256  // or a ',' that is outside of a comment
257  // and outside of quoted text before the leading '<'.
258  bInComment = false;
259  bInQuotesOutsideOfEmail = false;
260  for (i = iAd-1; 0 <= i; --i) {
261  c = aStr[i];
262  if (bInComment) {
263  if ('(' == c) {
264  if (!name.isEmpty()) {
265  name.prepend(' ');
266  }
267  bInComment = false;
268  } else {
269  name.prepend(c); // all comment stuff is part of the name
270  }
271  } else if (bInQuotesOutsideOfEmail) {
272  if (cQuotes == c) {
273  bInQuotesOutsideOfEmail = false;
274  } else if (c != '\\') {
275  name.prepend(c);
276  }
277  } else {
278  // found the start of this addressee ?
279  if (',' == c) {
280  break;
281  }
282  // stuff is before the leading '<' ?
283  if (iMailStart) {
284  if (cQuotes == c) {
285  bInQuotesOutsideOfEmail = true; // end of quoted text found
286  } else {
287  name.prepend(c);
288  }
289  } else {
290  switch (c.toLatin1()) {
291  case '<':
292  iMailStart = i;
293  break;
294  case ')':
295  if (!name.isEmpty()) {
296  name.prepend(' ');
297  }
298  bInComment = true;
299  break;
300  default:
301  if (' ' != c) {
302  mail.prepend(c);
303  }
304  }
305  }
306  }
307  }
308 
309  name = name.simplified();
310  mail = mail.simplified();
311 
312  if (mail.isEmpty()) {
313  return false;
314  }
315 
316  mail.append('@');
317 
318  // Loop forward until we find the end of the string
319  // or a ',' that is outside of a comment
320  // and outside of quoted text behind the trailing '>'.
321  bInComment = false;
322  bInQuotesOutsideOfEmail = false;
323  int parenthesesNesting = 0;
324  for (i = iAd+1; len > i; ++i) {
325  c = aStr[i];
326  if (bInComment) {
327  if (')' == c) {
328  if (--parenthesesNesting == 0) {
329  bInComment = false;
330  if (!name.isEmpty()) {
331  name.append(' ');
332  }
333  } else {
334  // nested ")", add it
335  name.append(')'); // name can't be empty here
336  }
337  } else {
338  if ('(' == c) {
339  // nested "("
340  ++parenthesesNesting;
341  }
342  name.append(c); // all comment stuff is part of the name
343  }
344  } else if (bInQuotesOutsideOfEmail) {
345  if (cQuotes == c) {
346  bInQuotesOutsideOfEmail = false;
347  } else if (c != '\\') {
348  name.append(c);
349  }
350  } else {
351  // found the end of this addressee ?
352  if (',' == c) {
353  break;
354  }
355  // stuff is behind the trailing '>' ?
356  if (iMailEnd) {
357  if (cQuotes == c) {
358  bInQuotesOutsideOfEmail = true; // start of quoted text found
359  } else {
360  name.append(c);
361  }
362  } else {
363  switch (c.toLatin1()) {
364  case '>':
365  iMailEnd = i;
366  break;
367  case '(':
368  if (!name.isEmpty()) {
369  name.append(' ');
370  }
371  if (++parenthesesNesting > 0) {
372  bInComment = true;
373  }
374  break;
375  default:
376  if (' ' != c) {
377  mail.append(c);
378  }
379  }
380  }
381  }
382  }
383  }
384 
385  name = name.simplified();
386  mail = mail.simplified();
387 
388  return !(name.isEmpty() || mail.isEmpty());
389 }
390 
391 Person::Ptr Person::fromFullName(const QString &fullName)
392 {
393  QString email, name;
394  extractEmailAddressAndName(fullName, email, name);
395  return Person::Ptr(new Person(name, email));
396 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Fri Jan 3 2014 22:20:29 by doxygen 1.8.3.1 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.11.5 API Reference

Skip menu "kdepimlibs-4.11.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • 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