• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeabc
 

tdeabc

  • tdeabc
vcardtool.cpp
1/*
2 This file is part of libtdeabc.
3 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <tqbuffer.h>
22#include <tqdatastream.h>
23#include <tqregexp.h>
24#include <tqstring.h>
25
26#include "agent.h"
27#include "key.h"
28#include "picture.h"
29#include "secrecy.h"
30#include "sound.h"
31
32#include "vcardtool.h"
33
34using namespace TDEABC;
35
36static bool needsEncoding( const TQString &value )
37{
38 uint length = value.length();
39 for ( uint i = 0; i < length; ++i ) {
40 char c = value.at( i ).latin1();
41 if ( (c < 33 || c > 126) && c != ' ' && c != '=' )
42 return true;
43 }
44
45 return false;
46}
47
48VCardTool::VCardTool()
49{
50 mAddressTypeMap.insert( "dom", Address::Dom );
51 mAddressTypeMap.insert( "intl", Address::Intl );
52 mAddressTypeMap.insert( "postal", Address::Postal );
53 mAddressTypeMap.insert( "parcel", Address::Parcel );
54 mAddressTypeMap.insert( "home", Address::Home );
55 mAddressTypeMap.insert( "work", Address::Work );
56 mAddressTypeMap.insert( "pref", Address::Pref );
57
58 mPhoneTypeMap.insert( "HOME", PhoneNumber::Home );
59 mPhoneTypeMap.insert( "WORK", PhoneNumber::Work );
60 mPhoneTypeMap.insert( "MSG", PhoneNumber::Msg );
61 mPhoneTypeMap.insert( "PREF", PhoneNumber::Pref );
62 mPhoneTypeMap.insert( "VOICE", PhoneNumber::Voice );
63 mPhoneTypeMap.insert( "FAX", PhoneNumber::Fax );
64 mPhoneTypeMap.insert( "CELL", PhoneNumber::Cell );
65 mPhoneTypeMap.insert( "VIDEO", PhoneNumber::Video );
66 mPhoneTypeMap.insert( "BBS", PhoneNumber::Bbs );
67 mPhoneTypeMap.insert( "MODEM", PhoneNumber::Modem );
68 mPhoneTypeMap.insert( "CAR", PhoneNumber::Car );
69 mPhoneTypeMap.insert( "ISDN", PhoneNumber::Isdn );
70 mPhoneTypeMap.insert( "PCS", PhoneNumber::Pcs );
71 mPhoneTypeMap.insert( "PAGER", PhoneNumber::Pager );
72}
73
74VCardTool::~VCardTool()
75{
76}
77
78// TODO: make list a const&
79TQString VCardTool::createVCards( Addressee::List list, VCard::Version version )
80{
81 VCard::List vCardList;
82
83 Addressee::List::ConstIterator addrIt;
84 Addressee::List::ConstIterator listEnd( list.constEnd() );
85 for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
86 VCard card;
87 TQStringList::ConstIterator strIt;
88
89 // ADR + LABEL
90 const Address::List addresses = (*addrIt).addresses();
91 for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
92 TQStringList address;
93
94 bool isEmpty = ( (*it).postOfficeBox().isEmpty() &&
95 (*it).extended().isEmpty() &&
96 (*it).street().isEmpty() &&
97 (*it).locality().isEmpty() &&
98 (*it).region().isEmpty() &&
99 (*it).postalCode().isEmpty() &&
100 (*it).country().isEmpty() );
101
102 address.append( (*it).postOfficeBox().replace( ';', "\\;" ) );
103 address.append( (*it).extended().replace( ';', "\\;" ) );
104 address.append( (*it).street().replace( ';', "\\;" ) );
105 address.append( (*it).locality().replace( ';', "\\;" ) );
106 address.append( (*it).region().replace( ';', "\\;" ) );
107 address.append( (*it).postalCode().replace( ';', "\\;" ) );
108 address.append( (*it).country().replace( ';', "\\;" ) );
109
110 VCardLine adrLine( "ADR", address.join( ";" ) );
111 if ( version == VCard::v2_1 && needsEncoding( address.join( ";" ) ) ) {
112 adrLine.addParameter( "charset", "UTF-8" );
113 adrLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
114 }
115
116 VCardLine labelLine( "LABEL", (*it).label() );
117 if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) {
118 labelLine.addParameter( "charset", "UTF-8" );
119 labelLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
120 }
121
122 bool hasLabel = !(*it).label().isEmpty();
123 TQMap<TQString, int>::ConstIterator typeIt;
124 for ( typeIt = mAddressTypeMap.constBegin(); typeIt != mAddressTypeMap.constEnd(); ++typeIt ) {
125 if ( typeIt.data() & (*it).type() ) {
126 adrLine.addParameter( "TYPE", typeIt.key() );
127 if ( hasLabel )
128 labelLine.addParameter( "TYPE", typeIt.key() );
129 }
130 }
131
132 if ( !isEmpty )
133 card.addLine( adrLine );
134 if ( hasLabel )
135 card.addLine( labelLine );
136 }
137
138 // AGENT
139 card.addLine( createAgent( version, (*addrIt).agent() ) );
140
141 // BDAY
142 card.addLine( VCardLine( "BDAY", createDateTime( (*addrIt).birthday()) ) );
143
144 // CATEGORIES
145 if ( version == VCard::v3_0 ) {
146 TQStringList categories = (*addrIt).categories();
147 TQStringList::Iterator catIt;
148 for ( catIt = categories.begin(); catIt != categories.end(); ++catIt )
149 (*catIt).replace( ',', "\\," );
150
151 VCardLine catLine( "CATEGORIES", categories.join( "," ) );
152 if ( version == VCard::v2_1 && needsEncoding( categories.join( "," ) ) ) {
153 catLine.addParameter( "charset", "UTF-8" );
154 catLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
155 }
156
157 card.addLine( catLine );
158 }
159
160 // CLASS
161 if ( version == VCard::v3_0 ) {
162 card.addLine( createSecrecy( (*addrIt).secrecy() ) );
163 }
164
165 // EMAIL
166 const TQStringList emails = (*addrIt).emails();
167 bool pref = true;
168 for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) {
169 VCardLine line( "EMAIL", *strIt );
170 if ( pref == true && emails.count() > 1 ) {
171 line.addParameter( "TYPE", "PREF" );
172 pref = false;
173 }
174 card.addLine( line );
175 }
176
177 // FN
178 VCardLine fnLine( "FN", TQString((*addrIt).formattedName()) );
179 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) {
180 fnLine.addParameter( "charset", "UTF-8" );
181 fnLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
182 }
183 card.addLine( fnLine );
184
185 // GEO
186 Geo geo = (*addrIt).geo();
187 if ( geo.isValid() ) {
188 TQString str;
189 str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() );
190 card.addLine( VCardLine( "GEO", str ) );
191 }
192
193 // KEY
194 const Key::List keys = (*addrIt).keys();
195 Key::List::ConstIterator keyIt;
196 for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt )
197 card.addLine( createKey( *keyIt ) );
198
199 // LOGO
200 card.addLine( createPicture( "LOGO", (*addrIt).logo() ) );
201
202 // MAILER
203 VCardLine mailerLine( "MAILER", TQString((*addrIt).mailer()) );
204 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) {
205 mailerLine.addParameter( "charset", "UTF-8" );
206 mailerLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
207 }
208 card.addLine( mailerLine );
209
210 // N
211 TQStringList name;
212 name.append( (*addrIt).familyName().replace( ';', "\\;" ) );
213 name.append( (*addrIt).givenName().replace( ';', "\\;" ) );
214 name.append( (*addrIt).additionalName().replace( ';', "\\;" ) );
215 name.append( (*addrIt).prefix().replace( ';', "\\;" ) );
216 name.append( (*addrIt).suffix().replace( ';', "\\;" ) );
217
218 VCardLine nLine( "N", name.join( ";" ) );
219 if ( version == VCard::v2_1 && needsEncoding( name.join( ";" ) ) ) {
220 nLine.addParameter( "charset", "UTF-8" );
221 nLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
222 }
223 card.addLine( nLine );
224
225 // NAME
226 VCardLine nameLine( "NAME", TQString((*addrIt).name()) );
227 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) {
228 nameLine.addParameter( "charset", "UTF-8" );
229 nameLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
230 }
231 card.addLine( nameLine );
232
233 // NICKNAME
234 if ( version == VCard::v3_0 )
235 card.addLine( VCardLine( "NICKNAME", TQString((*addrIt).nickName()) ) );
236
237 // NOTE
238 VCardLine noteLine( "NOTE", TQString((*addrIt).note()) );
239 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) {
240 noteLine.addParameter( "charset", "UTF-8" );
241 noteLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
242 }
243 card.addLine( noteLine );
244
245 // ORG
246 TQStringList organization;
247 organization.append( ( *addrIt ).organization().replace( ';', "\\;" ) );
248 if ( !( *addrIt ).department().isEmpty() )
249 organization.append( ( *addrIt ).department().replace( ';', "\\;" ) );
250 VCardLine orgLine( "ORG", organization.join( ";" ) );
251 if ( version == VCard::v2_1 && needsEncoding( organization.join( ";" ) ) ) {
252 orgLine.addParameter( "charset", "UTF-8" );
253 orgLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
254 }
255 card.addLine( orgLine );
256
257 // PHOTO
258 card.addLine( createPicture( "PHOTO", (*addrIt).photo() ) );
259
260 // PROID
261 if ( version == VCard::v3_0 )
262 card.addLine( VCardLine( "PRODID", TQString((*addrIt).productId()) ) );
263
264 // REV
265 card.addLine( VCardLine( "REV", createDateTime( (*addrIt).revision()) ) );
266
267 // ROLE
268 VCardLine roleLine( "ROLE", TQString((*addrIt).role()) );
269 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) {
270 roleLine.addParameter( "charset", "UTF-8" );
271 roleLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
272 }
273 card.addLine( roleLine );
274
275 // SORT-STRING
276 if ( version == VCard::v3_0 )
277 card.addLine( VCardLine( "SORT-STRING", TQString((*addrIt).sortString()) ) );
278
279 // SOUND
280 card.addLine( createSound( (*addrIt).sound() ) );
281
282 // TEL
283 const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers();
284 PhoneNumber::List::ConstIterator phoneIt;
285 for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt ) {
286 VCardLine line( "TEL", (*phoneIt).number() );
287
288 TQMap<TQString, int>::ConstIterator typeIt;
289 for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) {
290 if ( typeIt.data() & (*phoneIt).type() )
291 line.addParameter( "TYPE", typeIt.key() );
292 }
293
294 card.addLine( line );
295 }
296
297 // TITLE
298 VCardLine titleLine( "TITLE", TQString((*addrIt).title()) );
299 if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) {
300 titleLine.addParameter( "charset", "UTF-8" );
301 titleLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
302 }
303 card.addLine( titleLine );
304
305 // TZ
306 TimeZone timeZone = (*addrIt).timeZone();
307 if ( timeZone.isValid() ) {
308 TQString str;
309
310 int neg = 1;
311 if ( timeZone.offset() < 0 )
312 neg = -1;
313
314 str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ),
315 ( timeZone.offset() / 60 ) * neg,
316 ( timeZone.offset() % 60 ) * neg );
317
318 card.addLine( VCardLine( "TZ", str ) );
319 }
320
321 // UID
322 card.addLine( VCardLine( "UID", (*addrIt).uid() ) );
323
324 // UID
325 card.addLine( VCardLine( "URI", (*addrIt).uri() ) );
326
327 // URL
328 card.addLine( VCardLine( "URL", (*addrIt).url().url() ) );
329
330 // VERSION
331 if ( version == VCard::v2_1 )
332 card.addLine( VCardLine( "VERSION", "2.1" ) );
333 if ( version == VCard::v3_0 )
334 card.addLine( VCardLine( "VERSION", "3.0" ) );
335
336 // X-
337 const TQStringList customs = (*addrIt).customs();
338 for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) {
339 TQString identifier = "X-" + (*strIt).left( (*strIt).find( ":" ) );
340 TQString value = (*strIt).mid( (*strIt).find( ":" ) + 1 );
341 if ( value.isEmpty() )
342 continue;
343
344 VCardLine line( identifier, value );
345 if ( version == VCard::v2_1 && needsEncoding( value ) ) {
346 line.addParameter( "charset", "UTF-8" );
347 line.addParameter( "encoding", "QUOTED-PRINTABLE" );
348 }
349 card.addLine( line );
350 }
351
352 vCardList.append( card );
353 }
354
355 return VCardParser::createVCards( vCardList );
356}
357
358Addressee::List VCardTool::parseVCards( const TQString& vcard )
359{
360 static const TQChar semicolonSep( ';' );
361 static const TQChar commaSep( ',' );
362 TQString identifier;
363
364 Addressee::List addrList;
365 const VCard::List vCardList = VCardParser::parseVCards( vcard );
366
367 VCard::List::ConstIterator cardIt;
368 VCard::List::ConstIterator listEnd( vCardList.end() );
369 for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
370 Addressee addr;
371
372 const TQStringList idents = (*cardIt).identifiers();
373 TQStringList::ConstIterator identIt;
374 TQStringList::ConstIterator identEnd( idents.end() );
375 for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
376 const VCardLine::List lines = (*cardIt).lines( (*identIt) );
377 VCardLine::List::ConstIterator lineIt;
378
379 // iterate over the lines
380 for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
381 identifier = (*lineIt).identifier().lower();
382 // ADR
383 if ( identifier == "adr" ) {
384 Address address;
385 const TQStringList addrParts = splitString( semicolonSep, (*lineIt).value().asString() );
386 if ( addrParts.count() > 0 )
387 address.setPostOfficeBox( addrParts[ 0 ] );
388 if ( addrParts.count() > 1 )
389 address.setExtended( addrParts[ 1 ] );
390 if ( addrParts.count() > 2 )
391 address.setStreet( addrParts[ 2 ] );
392 if ( addrParts.count() > 3 )
393 address.setLocality( addrParts[ 3 ] );
394 if ( addrParts.count() > 4 )
395 address.setRegion( addrParts[ 4 ] );
396 if ( addrParts.count() > 5 )
397 address.setPostalCode( addrParts[ 5 ] );
398 if ( addrParts.count() > 6 )
399 address.setCountry( addrParts[ 6 ] );
400
401 int type = 0;
402
403 const TQStringList types = (*lineIt).parameters( "type" );
404 for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
405 type += mAddressTypeMap[ (*it).lower() ];
406
407 address.setType( type );
408 addr.insertAddress( address );
409 }
410
411 // AGENT
412 else if ( identifier == "agent" )
413 addr.setAgent( parseAgent( *lineIt ) );
414
415 // BDAY
416 else if ( identifier == "bday" ) {
417 TQString s((*lineIt).value().asString());
418 if ( s.length() > 0 )
419 addr.setBirthday( parseDateTime( s ) );
420 }
421
422 // CATEGORIES
423 else if ( identifier == "categories" ) {
424 const TQStringList categories = splitString( commaSep, (*lineIt).value().asString() );
425 addr.setCategories( categories );
426 }
427
428 // CLASS
429 else if ( identifier == "class" )
430 addr.setSecrecy( parseSecrecy( *lineIt ) );
431
432 // EMAIL
433 else if ( identifier == "email" ) {
434 const TQStringList types = (*lineIt).parameters( "type" );
435 addr.insertEmail( (*lineIt).value().asString(), types.findIndex( "PREF" ) != -1 );
436 }
437
438 // FN
439 else if ( identifier == "fn" )
440 addr.setFormattedName( (*lineIt).value().asString() );
441
442 // GEO
443 else if ( identifier == "geo" ) {
444 Geo geo;
445
446 const TQStringList geoParts = TQStringList::split( ';', (*lineIt).value().asString(), true );
447 geo.setLatitude( geoParts[ 0 ].toFloat() );
448 geo.setLongitude( geoParts[ 1 ].toFloat() );
449
450 addr.setGeo( geo );
451 }
452
453 // KEY
454 else if ( identifier == "key" )
455 addr.insertKey( parseKey( *lineIt ) );
456
457 // LABEL
458 else if ( identifier == "label" ) {
459 int type = 0;
460
461 const TQStringList types = (*lineIt).parameters( "type" );
462 for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
463 type += mAddressTypeMap[ (*it).lower() ];
464
465 bool available = false;
466 TDEABC::Address::List addressList = addr.addresses();
467 TDEABC::Address::List::Iterator it;
468 for ( it = addressList.begin(); it != addressList.end(); ++it ) {
469 if ( (*it).type() == type ) {
470 (*it).setLabel( (*lineIt).value().asString() );
471 addr.insertAddress( *it );
472 available = true;
473 break;
474 }
475 }
476
477 if ( !available ) { // a standalone LABEL tag
478 TDEABC::Address address( type );
479 address.setLabel( (*lineIt).value().asString() );
480 addr.insertAddress( address );
481 }
482 }
483
484 // LOGO
485 else if ( identifier == "logo" )
486 addr.setLogo( parsePicture( *lineIt ) );
487
488 // MAILER
489 else if ( identifier == "mailer" )
490 addr.setMailer( (*lineIt).value().asString() );
491
492 // N
493 else if ( identifier == "n" ) {
494 const TQStringList nameParts = splitString( semicolonSep, (*lineIt).value().asString() );
495 if ( nameParts.count() > 0 )
496 addr.setFamilyName( nameParts[ 0 ] );
497 if ( nameParts.count() > 1 )
498 addr.setGivenName( nameParts[ 1 ] );
499 if ( nameParts.count() > 2 )
500 addr.setAdditionalName( nameParts[ 2 ] );
501 if ( nameParts.count() > 3 )
502 addr.setPrefix( nameParts[ 3 ] );
503 if ( nameParts.count() > 4 )
504 addr.setSuffix( nameParts[ 4 ] );
505 }
506
507 // NAME
508 else if ( identifier == "name" )
509 addr.setName( (*lineIt).value().asString() );
510
511 // NICKNAME
512 else if ( identifier == "nickname" )
513 addr.setNickName( (*lineIt).value().asString() );
514
515 // NOTE
516 else if ( identifier == "note" )
517 addr.setNote( (*lineIt).value().asString() );
518
519 // ORGANIZATION
520 else if ( identifier == "org" ) {
521 const TQStringList orgParts = splitString( semicolonSep, (*lineIt).value().asString() );
522 if ( orgParts.count() > 0 )
523 addr.setOrganization( orgParts[ 0 ] );
524 if ( orgParts.count() > 1 )
525 addr.setDepartment( orgParts[ 1 ] );
526 }
527
528 // PHOTO
529 else if ( identifier == "photo" )
530 addr.setPhoto( parsePicture( *lineIt ) );
531
532 // PROID
533 else if ( identifier == "prodid" )
534 addr.setProductId( (*lineIt).value().asString() );
535
536 // REV
537 else if ( identifier == "rev" )
538 addr.setRevision( parseDateTime( (*lineIt).value().asString() ) );
539
540 // ROLE
541 else if ( identifier == "role" )
542 addr.setRole( (*lineIt).value().asString() );
543
544 // SORT-STRING
545 else if ( identifier == "sort-string" )
546 addr.setSortString( (*lineIt).value().asString() );
547
548 // SOUND
549 else if ( identifier == "sound" )
550 addr.setSound( parseSound( *lineIt ) );
551
552 // TEL
553 else if ( identifier == "tel" ) {
554 PhoneNumber phone;
555 phone.setNumber( (*lineIt).value().asString() );
556
557 int type = 0;
558
559 const TQStringList types = (*lineIt).parameters( "type" );
560 for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
561 type += mPhoneTypeMap[(*it).upper()];
562
563 phone.setType( type );
564
565 addr.insertPhoneNumber( phone );
566 }
567
568 // TITLE
569 else if ( identifier == "title" )
570 addr.setTitle( (*lineIt).value().asString() );
571
572 // TZ
573 else if ( identifier == "tz" ) {
574 TimeZone tz;
575 const TQString date = (*lineIt).value().asString();
576
577 int hours = date.mid( 1, 2).toInt();
578 int minutes = date.mid( 4, 2 ).toInt();
579 int offset = ( hours * 60 ) + minutes;
580 offset = offset * ( date[ 0 ] == '+' ? 1 : -1 );
581
582 tz.setOffset( offset );
583 addr.setTimeZone( tz );
584 }
585
586 // UID
587 else if ( identifier == "uid" )
588 addr.setUid( (*lineIt).value().asString() );
589
590 // URI
591 else if ( identifier == "uri" )
592 addr.setUri( (*lineIt).value().asString() );
593
594 // URL
595 else if ( identifier == "url" )
596 addr.setUrl( KURL( (*lineIt).value().asString() ) );
597
598 // X-
599 else if ( identifier.startsWith( "x-" ) ) {
600 const TQString key = (*lineIt).identifier().mid( 2 );
601 int dash = key.find( "-" );
602 addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), (*lineIt).value().asString() );
603 }
604 }
605 }
606
607 addrList.append( addr );
608 }
609
610 return addrList;
611}
612
613TQDateTime VCardTool::parseDateTime(const TQString &str)
614{
615 TQDateTime dateTime;
616
617 /* This regex matches one of the following formats (description taken from
618 https://www.w3.org/TR/NOTE-datetime, copyright remains of the respective documentation author(s))
619 Year: YYYY (eg 1997)
620 Year and month: YYYY-MM (eg 1997-07)
621 Complete date: YYYY-MM-DD (eg 1997-07-16)
622 Complete date plus hours and minutes: YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
623 Complete date plus hours, minutes and seconds: YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
624 Complete date plus hours, minutes, seconds and a decimal fraction of a second
625 YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
626 where:
627 YYYY = four-digit year
628 MM = two-digit month (01=January, etc.)
629 DD = two-digit day of month (01 through 31)
630 hh = two digits of hour (00 through 23) (am/pm NOT allowed)
631 mm = two digits of minute (00 through 59)
632 ss = two digits of second (00 through 59)
633 s = one or more digits representing a decimal fraction of a second
634 TZD = time zone designator (Z or +hh:mm or -hh:mm)
635 */
636 TQRegExp re("(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d+))?)?"
637 "(?:(Z)|([+-])(\\d{2}):(\\d{2})))?)?)?", true, false);
638 if (!re.exactMatch(str))
639 {
640 // Try alternative format if pattern does not match
641 /* This regex matches one of the following formats (description adapted from
642 https://www.w3.org/TR/NOTE-datetime, copyright remains of the respective documentation author(s))
643 Year: YYYY (eg 1997)
644 Year and month: YYYYMM (eg 199707)
645 Complete date: YYYYMMDD (eg 19970716)
646 Complete date plus hours and minutes: YYYYMMDDThhmmTZD (eg 19970716T1920+0100)
647 Complete date plus hours, minutes and seconds: YYYYMMDDThhmmssTZD (eg 19970716T192030+0100)
648 Complete date plus hours, minutes, seconds and a decimal fraction of a second
649 YYYYMMDDThhmmsslTZD (eg 19970716T19203045+0100)
650 where:
651 YYYY = four-digit year
652 MM = two-digit month (01=January, etc.)
653 DD = two-digit day of month (01 through 31)
654 hh = two digits of hour (00 through 23) (am/pm NOT allowed)
655 mm = two digits of minute (00 through 59)
656 ss = two digits of second (00 through 59)
657 l = one or more digits representing a decimal fraction of a second
658 TZD = time zone designator (Z or +hhmm or -hhmm)
659 */
660 re.setPattern("(\\d{4})(?:(\\d{2})(?:(\\d{2})(?:T(\\d{2})(\\d{2})(?:(\\d{2})(?:(\\d+))?)?"
661 "(?:(Z)|([+-])(\\d{2})(\\d{2})))?)?)?");
662 }
663 if (re.exactMatch(str))
664 {
665 // Insert date
666 dateTime.setDate(TQDate(re.cap(1).toInt(), // year
667 !re.cap(2).isEmpty() ? re.cap(2).toInt() : 1, // month
668 !re.cap(3).isEmpty() ? re.cap(3).toInt() : 1)); // day
669 if (!re.cap(4).isEmpty())
670 {
671 // Time was also specified
672 int millis = 0;
673 if (!re.cap(7).isEmpty())
674 {
675 millis += re.cap(7)[0].isDigit() ? re.cap(7)[0].digitValue() * 100 : 0;
676 millis += re.cap(7)[1].isDigit() ? re.cap(7)[1].digitValue() * 10 : 0;
677 millis += re.cap(7)[2].isDigit() ? re.cap(7)[2].digitValue() : 0;
678 }
679 dateTime.setTime(TQTime(re.cap(4).toInt(), // hours
680 re.cap(5).toInt(), // minutes
681 !re.cap(6).isEmpty() ? re.cap(6).toInt() : 0, // seconds
682 millis)); // milliseconds
683 // Add time offset if time not in UTC format
684 if (!re.cap(9).isEmpty())
685 {
686 int offset = re.cap(10).toInt() * 3600 + re.cap(11).toInt() * 60;
687 if (re.cap(9) == "+")
688 {
689 // Local time zone is ahead of UTC time
690 offset = -offset;
691 }
692 dateTime = dateTime.addSecs(offset);
693 }
694 }
695 }
696 return dateTime;
697}
698
699TQString VCardTool::createDateTime( const TQDateTime &dateTime )
700{
701 TQString str;
702
703 if ( dateTime.date().isValid() ) {
704 str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
705 dateTime.date().day() );
706 if ( dateTime.time().isValid() ) {
707 TQString tmp;
708 tmp.sprintf( "T%02d:%02d:%02dZ", dateTime.time().hour(), dateTime.time().minute(),
709 dateTime.time().second() );
710 str += tmp;
711 }
712 }
713
714 return str;
715}
716
717Picture VCardTool::parsePicture( const VCardLine &line )
718{
719 Picture pic;
720
721 const TQStringList params = line.parameterList();
722 if ( params.findIndex( "encoding" ) != -1 ) {
723 TQImage img;
724 img.loadFromData( line.value().asByteArray() );
725 pic.setData( img );
726 } else if ( params.findIndex( "value" ) != -1 ) {
727 if ( line.parameter( "value" ).lower() == "uri" )
728 pic.setUrl( line.value().asString() );
729 }
730
731 if ( params.findIndex( "type" ) != -1 )
732 pic.setType( line.parameter( "type" ) );
733
734 return pic;
735}
736
737VCardLine VCardTool::createPicture( const TQString &identifier, const Picture &pic )
738{
739 VCardLine line( identifier );
740
741 if ( pic.isIntern() ) {
742 if ( !pic.data().isNull() ) {
743 TQByteArray input;
744 TQBuffer buffer( input );
745 buffer.open( IO_WriteOnly );
746
747 TQImageIO iio( &buffer, "JPEG" );
748 iio.setImage( pic.data() );
749 iio.setQuality( 100 );
750 iio.write();
751
752 line.setValue( input );
753 line.addParameter( "encoding", "b" );
754 line.addParameter( "type", "image/jpeg" );
755 }
756 } else if ( !pic.url().isEmpty() ) {
757 line.setValue( pic.url() );
758 line.addParameter( "value", "URI" );
759 }
760
761 return line;
762}
763
764Sound VCardTool::parseSound( const VCardLine &line )
765{
766 Sound snd;
767
768 const TQStringList params = line.parameterList();
769 if ( params.findIndex( "encoding" ) != -1 )
770 snd.setData( line.value().asByteArray() );
771 else if ( params.findIndex( "value" ) != -1 ) {
772 if ( line.parameter( "value" ).lower() == "uri" )
773 snd.setUrl( line.value().asString() );
774 }
775
776/* TODO: support sound types
777 if ( params.contains( "type" ) )
778 snd.setType( line.parameter( "type" ) );
779*/
780
781 return snd;
782}
783
784VCardLine VCardTool::createSound( const Sound &snd )
785{
786 VCardLine line( "SOUND" );
787
788 if ( snd.isIntern() ) {
789 if ( !snd.data().isEmpty() ) {
790 line.setValue( snd.data() );
791 line.addParameter( "encoding", "b" );
792 // TODO: need to store sound type!!!
793 }
794 } else if ( !snd.url().isEmpty() ) {
795 line.setValue( snd.url() );
796 line.addParameter( "value", "URI" );
797 }
798
799 return line;
800}
801
802Key VCardTool::parseKey( const VCardLine &line )
803{
804 Key key;
805
806 const TQStringList params = line.parameterList();
807 if ( params.findIndex( "encoding" ) != -1 )
808 key.setBinaryData( line.value().asByteArray() );
809 else
810 key.setTextData( line.value().asString() );
811
812 if ( params.findIndex( "type" ) != -1 ) {
813 if ( line.parameter( "type" ).lower() == "x509" )
814 key.setType( Key::X509 );
815 else if ( line.parameter( "type" ).lower() == "pgp" )
816 key.setType( Key::PGP );
817 else {
818 key.setType( Key::Custom );
819 key.setCustomTypeString( line.parameter( "type" ) );
820 }
821 }
822
823 return key;
824}
825
826VCardLine VCardTool::createKey( const Key &key )
827{
828 VCardLine line( "KEY" );
829
830 if ( key.isBinary() ) {
831 if ( !key.binaryData().isEmpty() ) {
832 line.setValue( key.binaryData() );
833 line.addParameter( "encoding", "b" );
834 }
835 } else if ( !key.textData().isEmpty() )
836 line.setValue( key.textData() );
837
838 if ( key.type() == Key::X509 )
839 line.addParameter( "type", "X509" );
840 else if ( key.type() == Key::PGP )
841 line.addParameter( "type", "PGP" );
842 else if ( key.type() == Key::Custom )
843 line.addParameter( "type", key.customTypeString() );
844
845 return line;
846}
847
848Secrecy VCardTool::parseSecrecy( const VCardLine &line )
849{
850 Secrecy secrecy;
851
852 if ( line.value().asString().lower() == "public" )
853 secrecy.setType( Secrecy::Public );
854 if ( line.value().asString().lower() == "private" )
855 secrecy.setType( Secrecy::Private );
856 if ( line.value().asString().lower() == "confidential" )
857 secrecy.setType( Secrecy::Confidential );
858
859 return secrecy;
860}
861
862VCardLine VCardTool::createSecrecy( const Secrecy &secrecy )
863{
864 VCardLine line( "CLASS" );
865
866 int type = secrecy.type();
867
868 if ( type == Secrecy::Public )
869 line.setValue( "PUBLIC" );
870 else if ( type == Secrecy::Private )
871 line.setValue( "PRIVATE" );
872 else if ( type == Secrecy::Confidential )
873 line.setValue( "CONFIDENTIAL" );
874
875 return line;
876}
877
878Agent VCardTool::parseAgent( const VCardLine &line )
879{
880 Agent agent;
881
882 const TQStringList params = line.parameterList();
883 if ( params.findIndex( "value" ) != -1 ) {
884 if ( line.parameter( "value" ).lower() == "uri" )
885 agent.setUrl( line.value().asString() );
886 } else {
887 TQString str = line.value().asString();
888 str.replace( "\\n", "\r\n" );
889 str.replace( "\\N", "\r\n" );
890 str.replace( "\\;", ";" );
891 str.replace( "\\:", ":" );
892 str.replace( "\\,", "," );
893
894 const Addressee::List list = parseVCards( str );
895 if ( list.count() > 0 ) {
896 Addressee *addr = new Addressee;
897 *addr = list[ 0 ];
898 agent.setAddressee( addr );
899 }
900 }
901
902 return agent;
903}
904
905VCardLine VCardTool::createAgent( VCard::Version version, const Agent &agent )
906{
907 VCardLine line( "AGENT" );
908
909 if ( agent.isIntern() ) {
910 if ( agent.addressee() != 0 ) {
911 Addressee::List list;
912 list.append( *agent.addressee() );
913
914 TQString str = createVCards( list, version );
915 str.replace( "\r\n", "\\n" );
916 str.replace( ";", "\\;" );
917 str.replace( ":", "\\:" );
918 str.replace( ",", "\\," );
919 line.setValue( str );
920 }
921 } else if ( !agent.url().isEmpty() ) {
922 line.setValue( agent.url() );
923 line.addParameter( "value", "URI" );
924 }
925
926 return line;
927}
928
929TQStringList VCardTool::splitString( const TQChar &sep, const TQString &str )
930{
931 TQStringList list;
932 TQString value( str );
933
934 int start = 0;
935 int pos = value.find( sep, start );
936
937 while ( pos != -1 ) {
938 if ( value[ pos - 1 ] != '\\' ) {
939 if ( pos > start && pos <= (int)value.length() )
940 list << value.mid( start, pos - start );
941 else
942 list << TQString::null;
943
944 start = pos + 1;
945 pos = value.find( sep, start );
946 } else {
947 if ( pos != 0 ) {
948 value.replace( pos - 1, 2, sep );
949 pos = value.find( sep, pos );
950 } else
951 pos = value.find( sep, pos + 1 );
952 }
953 }
954
955 int l = value.length() - 1;
956 if ( value.mid( start, l - start + 1 ).length() > 0 )
957 list << value.mid( start, l - start + 1 );
958 else
959 list << TQString::null;
960
961 return list;
962}
KURL
TDEABC::Address
Postal address information.
Definition: address.h:56
TDEABC::Address::setPostalCode
void setPostalCode(const TQString &)
Sets the postal code.
Definition: address.cpp:221
TDEABC::Address::setExtended
void setExtended(const TQString &)
Sets the extended address information.
Definition: address.cpp:149
TDEABC::Address::setLocality
void setLocality(const TQString &)
Sets the locality, e.g.
Definition: address.cpp:185
TDEABC::Address::setType
void setType(int type)
Sets the type of address.
Definition: address.cpp:100
TDEABC::Address::List
TQValueList< Address > List
List of addresses.
Definition: address.h:64
TDEABC::Address::setRegion
void setRegion(const TQString &)
Sets the region, e.g.
Definition: address.cpp:203
TDEABC::Address::setLabel
void setLabel(const TQString &)
Sets the delivery label.
Definition: address.cpp:257
TDEABC::Address::setStreet
void setStreet(const TQString &)
Sets the street (including number).
Definition: address.cpp:167
TDEABC::Address::setCountry
void setCountry(const TQString &)
Sets the country.
Definition: address.cpp:239
TDEABC::Address::setPostOfficeBox
void setPostOfficeBox(const TQString &)
Sets the post office box.
Definition: address.cpp:131
TDEABC::Addressee
address book entry
Definition: addressee.src.h:75
TDEABC::Addressee::setUid
void setUid(const TQString &uid)
Set unique identifier.
Definition: addressee.src.cpp:166
TDEABC::Addressee::setCategories
void setCategories(const TQStringList &)
Set categories to given value.
Definition: addressee.src.cpp:778
TDEABC::Addressee::insertPhoneNumber
void insertPhoneNumber(const PhoneNumber &phoneNumber)
Insert a phone number.
Definition: addressee.src.cpp:460
TDEABC::Addressee::insertCustom
void insertCustom(const TQString &app, const TQString &name, const TQString &value)
Insert custom entry.
Definition: addressee.src.cpp:791
TDEABC::Addressee::setUri
void setUri(const TQString &uid)
Set unique resource identifier.
Definition: addressee.src.cpp:184
TDEABC::Addressee::insertEmail
void insertEmail(const TQString &email, bool preferred=false)
Insert an email address.
Definition: addressee.src.cpp:412
TDEABC::Addressee::insertAddress
void insertAddress(const Address &address)
Insert an address.
Definition: addressee.src.cpp:675
TDEABC::Addressee::addresses
Address::List addresses() const
Return list of all addresses.
Definition: addressee.src.cpp:723
TDEABC::Addressee::insertKey
void insertKey(const Key &key)
Insert a key.
Definition: addressee.src.cpp:534
TDEABC::Agent
Important!!!
Definition: agent.h:41
TDEABC::Agent::setAddressee
void setAddressee(Addressee *addressee)
Sets the addressee of the agent.
Definition: agent.cpp:96
TDEABC::Agent::setUrl
void setUrl(const TQString &url)
Sets a URL for the location of the agent file.
Definition: agent.cpp:90
TDEABC::Agent::addressee
Addressee * addressee() const
Returns the addressee object of this agent.
Definition: agent.cpp:112
TDEABC::Agent::url
TQString url() const
Returns the location URL of this agent.
Definition: agent.cpp:107
TDEABC::Agent::isIntern
bool isIntern() const
Returns whether the agent is described by a URL (extern) or by a addressee (intern).
Definition: agent.cpp:102
TDEABC::Geo
Geographic position.
Definition: geo.h:36
TDEABC::Geo::setLongitude
void setLongitude(float)
Sets the longitude.
Definition: geo.cpp:54
TDEABC::Geo::isValid
bool isValid() const
Returns, if this object contains a valid geographical position.
Definition: geo.cpp:70
TDEABC::Geo::setLatitude
void setLatitude(float)
Sets the latitude.
Definition: geo.cpp:38
TDEABC::Geo::longitude
float longitude() const
Returns the longitude.
Definition: geo.cpp:65
TDEABC::Geo::latitude
float latitude() const
Returns the latitude.
Definition: geo.cpp:49
TDEABC::Key
A class to store an encryption key.
Definition: key.h:34
TDEABC::PhoneNumber
Phonenumber information.
Definition: phonenumber.h:39
TDEABC::PhoneNumber::setType
void setType(int)
Sets the type.
Definition: phonenumber.cpp:93
TDEABC::PhoneNumber::setNumber
void setNumber(const TQString &)
Sets the number.
Definition: phonenumber.cpp:83
TDEABC::Sound
Class that holds a Sound clip for a contact.
Definition: sound.h:60
TDEABC::Sound::url
TQString url() const
Returns the location URL of this sound.
Definition: sound.cpp:89
TDEABC::Sound::setData
void setData(const TQByteArray &data)
Sets the raw data of the sound.
Definition: sound.cpp:72
TDEABC::Sound::isIntern
bool isIntern() const
Returns whether the sound is described by a URL (extern) or by the raw data (intern).
Definition: sound.cpp:78
TDEABC::Sound::setUrl
void setUrl(const TQString &url)
Sets a URL for the location of the sound file.
Definition: sound.cpp:66
TDEABC::Sound::data
TQByteArray data() const
Returns the raw data of this sound.
Definition: sound.cpp:94
TDEABC::TimeZone
Time zone information.
Definition: timezone.h:36
TDEABC::TimeZone::setOffset
void setOffset(int offset)
Set time zone offset relative to UTC.
Definition: timezone.cpp:37
TDEABC::TimeZone::offset
int offset() const
Return offset in minutes relative to UTC.
Definition: timezone.cpp:43
TDEABC::TimeZone::asString
TQString asString() const
Return string representation of time zone offset.
Definition: timezone.cpp:69
TDEABC::TimeZone::isValid
bool isValid() const
Return, if this time zone object is valid.
Definition: timezone.cpp:48
TDEABC
static data, shared by ALL addressee objects
Definition: address.h:48
TDEStdAccel::key
int key(StdAccel id)
TDEStdAccel::name
TQString name(StdAccel id)

tdeabc

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

tdeabc

Skip menu "tdeabc"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeabc by doxygen 1.9.4
This website is maintained by Timothy Pearson.