00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
#include "kogroupware.h"
00038
00039
#include "freebusymanager.h"
00040
#include "calendarview.h"
00041
#include "mailscheduler.h"
00042
#include "kogroupwareincomingdialog.h"
00043
#include "koviewmanager.h"
00044
#include "kocore.h"
00045
00046
#include <libkdepim/email.h>
00047
#include <ktnef/ktnefparser.h>
00048
#include <ktnef/ktnefmessage.h>
00049
#include <ktnef/ktnefdefs.h>
00050
00051
#include <libkcal/incidencebase.h>
00052
#include <libkcal/attendee.h>
00053
#include <libkcal/freebusy.h>
00054
#include <libkcal/journal.h>
00055
#include <libkcal/calendarlocal.h>
00056
#include <libkcal/icalformat.h>
00057
00058
#include <kabc/phonenumber.h>
00059
#include <kabc/vcardconverter.h>
00060
00061
#include <kdebug.h>
00062
#include <kmessagebox.h>
00063
#include <ktempfile.h>
00064
#include <kio/netaccess.h>
00065
#include <kapplication.h>
00066
#include <kconfig.h>
00067
#include <dcopclient.h>
00068
#include <dcopref.h>
00069
#include <kstandarddirs.h>
00070
#include <kdirwatch.h>
00071
00072
#include <qfile.h>
00073
#include <qbuffer.h>
00074
#include <qregexp.h>
00075
00076
#include <mimelib/enum.h>
00077
00078
#include <stdlib.h>
00079
#include <time.h>
00080
#include <qdir.h>
00081
#include "koprefs.h"
00082
00083 FreeBusyManager *KOGroupware::mFreeBusyManager = 0;
00084
00085 KOGroupware *KOGroupware::mInstance = 0;
00086
00087 KOGroupware *KOGroupware::create(
CalendarView *view,
00088 KCal::Calendar *calendar )
00089 {
00090
if( !mInstance )
00091 mInstance =
new KOGroupware( view, calendar );
00092
return mInstance;
00093 }
00094
00095 KOGroupware *KOGroupware::instance()
00096 {
00097
00098 Q_ASSERT( mInstance );
00099
return mInstance;
00100 }
00101
00102
00103 KOGroupware::KOGroupware(
CalendarView* view, KCal::Calendar* calendar )
00104 :
QObject( 0, "kmgroupware_instance" )
00105 {
00106 mView = view;
00107 mCalendar = calendar;
00108
00109
00110 KDirWatch* watcher = KDirWatch::self();
00111 watcher->addDir( locateLocal(
"data",
"korganizer/income.accepted/" ) );
00112 watcher->addDir( locateLocal(
"data",
"korganizer/income.cancel/" ) );
00113 watcher->addDir( locateLocal(
"data",
"korganizer/income.reply/" ) );
00114 connect( watcher, SIGNAL( dirty(
const QString& ) ),
00115
this, SLOT( incomingDirChanged(
const QString& ) ) );
00116
00117 incomingDirChanged( locateLocal(
"data",
"korganizer/income.accepted/" ) );
00118 incomingDirChanged( locateLocal(
"data",
"korganizer/income.cancel/" ) );
00119 incomingDirChanged( locateLocal(
"data",
"korganizer/income.reply/" ) );
00120 }
00121
00122 FreeBusyManager *KOGroupware::freeBusyManager()
00123 {
00124
if ( !mFreeBusyManager ) {
00125 mFreeBusyManager =
new FreeBusyManager(
this,
"freebusymanager" );
00126 mFreeBusyManager->setCalendar( mCalendar );
00127 connect( mCalendar, SIGNAL( calendarChanged() ),
00128 mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00129 }
00130
00131
return mFreeBusyManager;
00132 }
00133
00134
void KOGroupware::incomingDirChanged(
const QString& path )
00135 {
00136
const QString incomingDirName = locateLocal(
"data",
"korganizer/" )
00137 +
"income.";
00138
if ( !path.startsWith( incomingDirName ) ) {
00139 kdDebug(5850) <<
"incomingDirChanged: Wrong dir " << path << endl;
00140
return;
00141 }
00142
QString action = path.mid( incomingDirName.length() );
00143
while ( action.length() > 0 && action[ action.length()-1 ] ==
'/' )
00144
00145 action.truncate( action.length()-1 );
00146
00147
00148
QDir dir( path );
00149
QStringList files = dir.entryList( QDir::Files );
00150
if ( files.count() == 0 )
00151
00152
return;
00153
00154
00155
QFile f( path +
"/" + files[0] );
00156
if (!f.open(IO_ReadOnly)) {
00157 kdError(5850) <<
"Can't open file '" << files[0] <<
"'" << endl;
00158
return;
00159 }
00160
QTextStream t(&f);
00161 t.setEncoding( QTextStream::UnicodeUTF8 );
00162
QString receiver = KPIM::getEmailAddr( t.readLine() );
00163
QString iCal = t.read();
00164
00165 ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar, iCal );
00166
if ( !message ) {
00167
QString errorMessage;
00168
if (mFormat.exception())
00169 errorMessage =
"\nError message: " + mFormat.exception()->message();
00170 kdDebug(5850) <<
"MailScheduler::retrieveTransactions() Error parsing"
00171 << errorMessage << endl;
00172 f.close();
00173
return;
00174 }
else
00175 f.remove();
00176
00177 KCal::Scheduler::Method method =
00178 static_cast<KCal::Scheduler::Method>( message->method() );
00179 KCal::ScheduleMessage::Status status = message->status();
00180 KCal::Incidence* incidence =
00181 dynamic_cast<KCal::Incidence*>( message->event() );
00182 KCal::MailScheduler scheduler( mCalendar );
00183
if ( action.startsWith(
"accepted" ) ) {
00184
00185 KCal::Attendee::List attendees = incidence->attendees();
00186 KCal::Attendee::List::ConstIterator it;
00187
for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00188
if( (*it)->email() == receiver ) {
00189 (*it)->setStatus( KCal::Attendee::Accepted );
00190 (*it)->setRSVP(
false);
00191
break;
00192 }
00193 }
00194 scheduler.acceptTransaction( incidence, method, status );
00195 }
else if ( action.startsWith(
"cancel" ) )
00196
00197 mCalendar->deleteIncidence( incidence );
00198
else if ( action.startsWith(
"reply" ) )
00199 scheduler.acceptTransaction( incidence, method, status );
00200
else
00201 kdError(5850) <<
"Unknown incoming action " << action << endl;
00202 mView->updateView();
00203 }
00204
00205
static void vPartMicroParser(
const QString& str,
QString& s )
00206 {
00207
QString line;
00208 uint len = str.length();
00209
00210
for( uint i=0; i<len; ++i) {
00211
if( str[i] ==
'\r' || str[i] ==
'\n' ) {
00212
if( str[i] ==
'\r' )
00213 ++i;
00214
if( i+1 < len && str[i+1] ==
' ' ) {
00215
00216 ++i;
00217 }
else {
00218
00219
if( line.startsWith( s ) ) {
00220 s = line.mid( s.length() + 1 );
00221
return;
00222 }
00223 line =
"";
00224 }
00225 }
else {
00226 line += str[i];
00227 }
00228 }
00229 s.truncate(0);
00230 }
00231
00232
static void string2HTML(
QString& str ) {
00233 str.replace(
QChar(
'&' ),
"&" );
00234 str.replace(
QChar(
'<' ),
"<" );
00235 str.replace(
QChar(
'>' ),
">" );
00236 str.replace(
QChar(
'\"' ),
""" );
00237 str.replace(
"\\n",
"<br>" );
00238 str.replace(
"\\,",
"," );
00239 }
00240
00241
static QString meetingDetails( Incidence* incidence, Event* event )
00242 {
00243
00244
00245
QString html;
00246
00247
QString sSummary = i18n(
"Summary unspecified" );
00248
if ( incidence ) {
00249
if ( ! incidence->summary().isEmpty() ) {
00250 sSummary = incidence->summary();
00251 string2HTML( sSummary );
00252 }
00253 }
00254
00255
QString sLocation = i18n(
"Location unspecified" );
00256
if ( incidence ) {
00257
if ( ! incidence->location().isEmpty() ) {
00258 sLocation = incidence->location();
00259 string2HTML( sLocation );
00260 }
00261 }
00262
00263
QString dir = ( QApplication::reverseLayout() ?
"rtl" :
"ltr" );
00264 html =
QString(
"<div dir=\"%1\">\n").arg(dir);
00265
00266 html +=
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
00267
00268
00269 html +=
"<tr>";
00270 html +=
"<td>" + i18n(
"What:" ) +
"</td>";
00271 html +=
"<td>" + sSummary +
"</td>";
00272 html +=
"</tr>\n";
00273
00274
00275 html +=
"<tr>";
00276 html +=
"<td>" + i18n(
"Where:" ) +
"</td>";
00277 html +=
"<td>" + sLocation +
"</td>";
00278 html +=
"</tr>\n";
00279
00280
00281 html +=
"<tr>";
00282 html +=
"<td>" + i18n(
"Start Time:" ) +
"</td>";
00283 html +=
"<td>";
00284
if ( ! event->doesFloat() ) {
00285 html += i18n(
"%1: Start Date, %2: Start Time",
"%1 %2")
00286 .arg( event->dtStartDateStr(), event->dtStartTimeStr() );
00287 }
else {
00288 html += i18n(
"%1: Start Date",
"%1 (time unspecified)")
00289 .arg( event->dtStartDateStr() );
00290 }
00291 html +=
"</td>";
00292 html +=
"</tr>\n";
00293
00294
00295 html +=
"<tr>";
00296 html +=
"<td>" + i18n(
"End Time:" ) +
"</td>";
00297 html +=
"<td>";
00298
if ( event->hasEndDate() ) {
00299
if ( ! event->doesFloat() ) {
00300 html += i18n(
"%1: End Date, %2: End Time",
"%1 %2")
00301 .arg( event->dtEndDateStr(), event->dtEndTimeStr() );
00302 }
else {
00303 html += i18n(
"%1: End Date",
"%1 (time unspecified)")
00304 .arg( event->dtEndDateStr() );
00305 }
00306 }
else {
00307 html += i18n(
"Unspecified" );
00308 }
00309 html +=
"</td>";
00310 html +=
"</tr>\n";
00311
00312
00313
if ( !event->doesFloat() && event->hasEndDate() ) {
00314 html +=
"<tr>";
00315
QTime sDuration, t;
00316
int secs = event->dtStart().secsTo( event->dtEnd() );
00317 t = sDuration.addSecs( secs );
00318 html +=
"<td>" + i18n(
"Duration:" ) +
"</td>";
00319 html +=
"<td>";
00320
if ( t.hour() > 0 ) {
00321 html += i18n(
"1 hour ",
"%n hours ", t.hour() );
00322 }
00323
if ( t.minute() > 0 ) {
00324 html += i18n(
"1 minute ",
"%n minutes ", t.minute() );
00325 }
00326 html +=
"</td>";
00327 html +=
"</tr>\n";
00328 }
00329
00330 html +=
"</table>\n";
00331 html +=
"</div>\n";
00332
00333
return html;
00334 }
00335
00336
static QString taskDetails( Incidence* incidence )
00337 {
00338
00339
00340
QString html;
00341
00342
QString sSummary = i18n(
"Summary unspecified" );
00343
QString sDescr = i18n(
"Description unspecified" );
00344
if ( incidence ) {
00345
if ( ! incidence->summary().isEmpty() ) {
00346 sSummary = incidence->summary();
00347 }
00348
if ( ! incidence->description().isEmpty() ) {
00349 sDescr = incidence->description();
00350 }
00351 }
00352 html =
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
00353
00354
00355 html +=
"<tr>";
00356 html +=
"<td>" + i18n(
"Summary:" ) +
"</td>";
00357 html +=
"<td>" + sSummary +
"</td>";
00358 html +=
"</tr>\n";
00359
00360
00361 html +=
"<tr>";
00362 html +=
"<td>" + i18n(
"Description:" ) +
"</td>";
00363 html +=
"<td>" + sDescr +
"</td>";
00364 html +=
"</tr>\n";
00365
00366 html +=
"</table>\n";
00367
00368
return html;
00369 }
00370
00371
QString KOGroupware::formatICal(
const QString& iCal )
00372 {
00373 KCal::CalendarLocal cl( mCalendar->timeZoneId() );
00374 ICalFormat format;
00375 format.fromString( &cl, iCal );
00376
00377
00378
if( cl.events().count() == 0 && cl.todos().count() == 0 ) {
00379 kdDebug(5850) <<
"No iCal in this one\n";
00380
return QString();
00381 }
00382
00383
00384
00385 Incidence* incidence = 0;
00386 Event* event = 0;
00387 Todo* todo = 0;
00388
if( cl.events().count() > 0 )
00389 incidence = event = cl.events().first();
00390
else
00391 incidence = todo = cl.todos().first();
00392
00393
00394
QString sMethod;
00395
00396 sMethod =
"METHOD";
00397 vPartMicroParser( iCal, sMethod );
00398 sMethod = sMethod.lower();
00399
00400
00401
QString html;
00402
if( sMethod ==
"request" ) {
00403
if( event ) {
00404 html = i18n(
"<h2>You have been invited to this meeting</h2>" );
00405 html += meetingDetails( incidence, event );
00406 }
else {
00407 html = i18n(
"<h2>You have been assigned this task</h2>" );
00408 html += taskDetails( incidence );
00409 }
00410 }
else if( sMethod ==
"reply" ) {
00411 Attendee::List attendees = incidence->attendees();
00412
if( attendees.count() == 0 ) {
00413 kdDebug(5850) <<
"No attendees in the iCal reply!\n";
00414
return QString();
00415 }
00416
if( attendees.count() != 1 )
00417 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
00418 <<
"but is " << attendees.count() << endl;
00419 Attendee* attendee = *attendees.begin();
00420
00421
switch( attendee->status() ) {
00422
case Attendee::Accepted:
00423
if( event ) {
00424 html = i18n(
"<h2>Sender accepts this meeting invitation</h2>" );
00425 html += meetingDetails( incidence, event );
00426 }
else {
00427 html = i18n(
"<h2>Sender accepts this task</h2>" );
00428 html += taskDetails( incidence );
00429 }
00430
break;
00431
00432
case Attendee::Tentative:
00433
if( event ) {
00434 html = i18n(
"<h2>Sender tentatively accepts this "
00435
"meeting invitation</h2>" );
00436 html += meetingDetails( incidence, event );
00437 }
else {
00438 html = i18n(
"<h2>Sender tentatively accepts this task</h2>" );
00439 html += taskDetails( incidence );
00440 }
00441
break;
00442
00443
case Attendee::Declined:
00444
if( event ) {
00445 html = i18n(
"<h2>Sender declines this meeting invitation</h2>" );
00446 html += meetingDetails( incidence, event );
00447 }
else {
00448 html = i18n(
"<h2>Sender declines this task</h2>" );
00449 html += taskDetails( incidence );
00450 }
00451
break;
00452
00453
default:
00454
if( event ) {
00455 html = i18n(
"<h2>Unknown response to this meeting invitation</h2>" );
00456 html += meetingDetails( incidence, event );
00457 }
else {
00458 html = i18n(
"<h2>Unknown response to this task</h2>" );
00459 html += taskDetails( incidence );
00460 }
00461 }
00462 }
else if( sMethod ==
"cancel" ) {
00463
if( event ) {
00464 html = i18n(
"<h2>This meeting has been canceled</h2>" );
00465 html += meetingDetails( incidence, event );
00466 }
else {
00467 html = i18n(
"<h2>This task was canceled</h2>" );
00468 html += taskDetails( incidence );
00469 }
00470 }
00471
00472
00473 html +=
"<br> <br> <br>";
00474 html +=
"<table border=\"0\" cellspacing=\"0\"><tr><td> </td><td>";
00475
if( sMethod ==
"request" || sMethod ==
"update" ) {
00476
00477 html +=
"<a href=\"kmail:groupware_request_accept\"><b>";
00478 html += i18n(
"[Accept]" );
00479 html +=
"</b></a></td><td> </td><td>";
00480
00481 html +=
"<a href=\"kmail:groupware_request_accept conditionally\"><b>";
00482 html += i18n(
"Accept conditionally",
"[Accept cond.]" );
00483 html +=
"</b></a></td><td> </td><td>";
00484
00485 html +=
"<a href=\"kmail:groupware_request_decline\"><b>";
00486 html += i18n(
"[Decline]" );
00487
if( event ) {
00488
00489 html +=
"</b></a></td><td> </td><td>";
00490 html +=
"<a href=\"kmail:groupware_request_check\"><b>";
00491 html += i18n(
"[Check my calendar...]" );
00492 }
00493 }
else if( sMethod ==
"reply" ) {
00494
00495 html +=
"<a href=\"kmail:groupware_reply#%1\"><b>";
00496
if( event )
00497 html += i18n(
"[Enter this into my calendar]" );
00498
else
00499 html += i18n(
"[Enter this into my task list]" );
00500 }
else if( sMethod ==
"cancel" ) {
00501
00502 html +=
"<a href=\"kmail:groupware_cancel\"><b>";
00503 html += i18n(
"[Remove this from my calendar]" );
00504 }
00505 html +=
"</b></a></td></tr></table>";
00506
00507
QString sDescr = incidence->description();
00508
if( ( sMethod ==
"request" || sMethod ==
"cancel" ) && !sDescr.isEmpty() ) {
00509 string2HTML( sDescr );
00510 html +=
"<br> <br> <br><u>" + i18n(
"Description:")
00511 +
"</u><br><table border=\"0\"><tr><td> </td><td>";
00512 html += sDescr +
"</td></tr></table>";
00513 }
00514 html +=
" <br> <br><u>" + i18n(
"Original message:" ) +
"</u>";
00515
00516
return html;
00517 }
00518
00519
QString KOGroupware::formatTNEF(
const QByteArray& tnef )
00520 {
00521
QString vPart = msTNEFToVPart( tnef );
00522
QString iCal = formatICal( vPart );
00523
if( !iCal.isEmpty() )
00524
return iCal;
00525
return vPart;
00526 }
00527
00528
bool KOGroupware::incomingEventRequest(
const QString& request,
00529
const QString& receiver,
00530
const QString& vCalIn )
00531 {
00532
00533 EventState state;
00534
if( request ==
"accept" )
00535 state = Accepted;
00536
else if( request ==
"accept conditionally" )
00537 state = ConditionallyAccepted;
00538
else if( request ==
"decline" )
00539 state = Declined;
00540
else if( request ==
"check" )
00541 state = Request;
00542
else
00543
return false;
00544
00545
00546
00547 KCal::ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar,
00548 vCalIn );
00549
if( message ) {
00550 kdDebug(5850) <<
"KOGroupware::incomingEventRequest: got message '"
00551 << vCalIn <<
"'" << endl;
00552 }
else {
00553
QString errorMessage;
00554
if( mFormat.exception() ) {
00555 errorMessage = mFormat.exception()->message();
00556 }
00557 kdDebug(5850) <<
"KOGroupware::incomingEventRequest() Error parsing "
00558 <<
"message: " << errorMessage << endl;
00559
00560
return false;
00561 }
00562
00563 KCal::Incidence* event = dynamic_cast<KCal::Incidence*>( message->event() );
00564 Q_ASSERT( event );
00565
if( !event ) {
00566 kdDebug(5850) <<
"KOGroupware::incomingEventRequest(): Not an event???\n";
00567
return false;
00568 }
00569
00570
00571
00572
if( state == Request ) {
00573
00574 KOGroupwareIncomingDialog dlg( event );
00575
int ret = dlg.exec();
00576
if( ret == QDialog::Rejected ) {
00577
00578 kdDebug(5850) <<
"KOGroupware::incomingEventRequest(): User canceled\n";
00579
return false;
00580 }
00581
00582
if( dlg.isDeclined() )
00583 state = Declined;
00584
else if( dlg.isConditionallyAccepted() )
00585 state = ConditionallyAccepted;
00586
else if( dlg.isAccepted() )
00587 state = Accepted;
00588
else
00589 kdDebug(5850) <<
"KOGroupware::incomingEventRequest(): unknown "
00590 <<
"event request state" << endl;
00591 }
00592
00593
00594
00595
#if 0
00596
00597
00598 Alarm::List alarms = event->alarms();
00599 Alarm::List::ConstIterator it;
00600
for ( it = alarms.begin(); it != alarms.end(); ++it) {
00601
if ( (*it)->hasTime() ) {
00602
QDateTime t = (*it)->time();
00603
int offset = event->dtStart().secsTo( t );
00604
if( offset > 0 )
00605
00606 kdDebug(5850) <<
"Warning: Alarm fires after the event\n";
00607 }
else {
00608
int offset = (*it)->offset().asSeconds();
00609
if( offset > 0 ) {
00610
00611 Duration d( -offset );
00612 (*it)->setOffset( d );
00613 }
00614 }
00615 }
00616
#endif
00617
00618
00619
00620
00621
00622
00623 KCal::MailScheduler scheduler( mCalendar );
00624
if( state == Accepted || state == ConditionallyAccepted ) {
00625 scheduler.acceptTransaction( event,
00626 (KCal::Scheduler::Method)message->method(),
00627 message->status() );
00628 mView->updateView();
00629 }
00630
00631 KCal::Attendee::List attendees = event->attendees();
00632 KCal::Attendee::List::ConstIterator it;
00633 KCal::Attendee* myself = 0;
00634
00635
00636
for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00637
if( (*it)->email() == receiver ) {
00638
00639
00640 myself = (*it);
00641
break;
00642 }
00643
00644
if ( KOPrefs::instance()->thatIsMe( (*it)->email() ) ) {
00645
00646
00647 myself = (*it);
00648 }
00649 }
00650
00651 Q_ASSERT( myself );
00652
00653 KCal::Attendee* newMyself = 0;
00654
if( myself ) {
00655
switch( state ) {
00656
case Accepted:
00657 myself->setStatus( KCal::Attendee::Accepted );
00658
break;
00659
case ConditionallyAccepted:
00660 myself->setStatus( KCal::Attendee::Tentative );
00661
break;
00662
case Declined:
00663 myself->setStatus( KCal::Attendee::Declined );
00664
break;
00665
default:
00666 ;
00667 };
00668
00669
00670 myself->setRSVP(
false);
00671
00672 event->updated();
00673
00674 newMyself =
new KCal::Attendee( myself->name(),
00675 receiver.isEmpty() ?
00676 myself->email() :
00677 receiver,
00678 myself->RSVP(),
00679 myself->status(),
00680 myself->role(),
00681 myself->uid() );
00682 }
00683
00684 event->updated();
00685
00686
00687
00688
00689
00690
00691
00692
00693 Incidence* newIncidence = event->clone();
00694 Event* newEvent = static_cast<KCal::Event*>( newIncidence );
00695
00696
#if 0
00697
00698
00699
00700
00701
bool stripAlarms =
false;
00702 emit getStripAlarmsForSending( stripAlarms );
00703
if( stripAlarms )
00704
00705 newEvent->clearAlarms();
00706
#endif
00707
00708 newEvent->clearAttendees();
00709
if( newMyself )
00710 newEvent->addAttendee( newMyself );
00711
00712
00713
QString messageText =
00714 mFormat.createScheduleMessage( newEvent, KCal::Scheduler::Reply );
00715 scheduler.performTransaction( newEvent, KCal::Scheduler::Reply );
00716
00717
00718
if( vCalIn.contains(
"PRODID:-//Microsoft" ) ) {
00719
00720 Attendee* organizer =
new KCal::Attendee( i18n(
"Organizer"),
00721 event->organizer(),
false,
00722 KCal::Attendee::Accepted );
00723 event->addAttendee( organizer );
00724 }
00725
00726 kdDebug(5850) <<
"Done" << endl;
00727
return true;
00728 }
00729
00734
void KOGroupware::incomingResourceRequest(
const QValueList<
QPair<
QDateTime,
00735 QDateTime> >& busy,
00736
const QCString& resource,
00737
const QString& vCalIn,
00738
bool& vCalInOK,
00739
QString& vCalOut,
00740
bool& vCalOutOK,
00741
bool& isFree,
00742 QDateTime& start,
00743 QDateTime& end )
00744 {
00745
00746
00747 KCal::ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar,
00748 vCalIn );
00749
if( message )
00750 vCalInOK =
true;
00751
else {
00752
QString errorMessage;
00753
if( mFormat.exception() ) {
00754 errorMessage = mFormat.exception()->message();
00755 }
00756 kdDebug(5850) <<
"KOGroupware::incomingResourceRequest() Error parsing "
00757
"message: " << errorMessage << endl;
00758 vCalInOK =
false;
00759
00760
return;
00761 }
00762
00763 KCal::Event* event = dynamic_cast<KCal::Event*>( message->event() );
00764 Q_ASSERT( event );
00765
if( !event ) {
00766
00767 vCalInOK =
false;
00768
return;
00769 }
00770
00771
00772
00773 start = event->dtStart();
00774 end = event->dtEnd();
00775 isFree =
true;
00776
QValueList<QPair<QDateTime, QDateTime> >::ConstIterator it;
00777
for( it = busy.begin(); it != busy.end(); ++it ) {
00778
if( (*it).second <= start || (*it).first >= end )
00779
00780
continue;
00781
else {
00782 isFree =
false;
00783
break;
00784 }
00785 }
00786
00787
00788 KCal::Attendee::List attendees = event->attendees();
00789 KCal::Attendee* resourceAtt = 0;
00790
00791
00792
00793 KCal::Attendee::List::ConstIterator it2;
00794
for( it2 = attendees.begin(); it2 != attendees.end(); ++it2 ) {
00795
if( (*it2)->email().utf8() == resource ) {
00796 resourceAtt = *it2;
00797
break;
00798 }
00799 }
00800 Q_ASSERT( resourceAtt );
00801
if( resourceAtt ) {
00802
if( isFree )
00803 resourceAtt->setStatus( KCal::Attendee::Accepted );
00804
else
00805 resourceAtt->setStatus( KCal::Attendee::Declined );
00806 }
else {
00807 vCalOutOK =
false;
00808
return;
00809 }
00810
00811
00812
QString messageText =
00813 mFormat.createScheduleMessage( event, KCal::Scheduler::Reply );
00814
00815 vCalOut = messageText;
00816 vCalOutOK =
true;
00817
return;
00818 }
00819
00820
00825
bool KOGroupware::incidenceAnswer(
const QString& vCal )
00826 {
00827
00828 KCal::ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar,
00829 vCal );
00830
if( !message ) {
00831
00832 KMessageBox::
00833 error( mView,
00834 i18n(
"<b>There was a problem parsing the iCal data:</b><br>%1" )
00835 .arg( mFormat.exception()->message() ) );
00836
return false;
00837 }
00838
00839 KCal::IncidenceBase* incidence = message->event();
00840
00841
00842
QString uid = incidence->uid();
00843 KCal::MailScheduler scheduler( mCalendar );
00844
if( !scheduler.acceptTransaction( incidence,
00845 (KCal::Scheduler::Method)message->method(),
00846 message->status() ) ) {
00847 KMessageBox::error( mView, i18n(
"Scheduling failed") );
00848
return false;
00849 }
00850
00851 mView->updateView();
00852
return true;
00853 }
00854
00855
bool KOGroupware::cancelIncidence(
const QString& iCal )
00856 {
00857
00858 KCal::ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar,
00859 iCal );
00860
if( !message ) {
00861
00862 KMessageBox::
00863 error( mView,
00864 i18n(
"<b>There was a problem parsing the iCal data:</b><br>%1" )
00865 .arg( mFormat.exception()->message() ) );
00866
return false;
00867 }
00868
00869 KCal::IncidenceBase* incidence = message->event();
00870
00871
00872 Event* event = mCalendar->event( incidence->uid() );
00873
if( !event )
00874
return false;
00875
00876 mCalendar->deleteEvent( event );
00877
return true;
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
bool KOGroupware::sendICalMessage(
QWidget* parent,
00887 KCal::Scheduler::Method method,
00888 Incidence* incidence,
bool isDeleting )
00889 {
00890
bool isOrganizer = KOPrefs::instance()->thatIsMe( incidence->organizer() );
00891
00892
int rc = 0;
00893
if( isOrganizer ) {
00894
00895
bool otherPeople =
false;
00896 Attendee::List attendees = incidence->attendees();
00897 Attendee::List::ConstIterator it;
00898
for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00899
00900
if ( !KOPrefs::instance()->thatIsMe( (*it)->email() ) ) {
00901 otherPeople =
true;
00902
break;
00903 }
00904 }
00905
if( !otherPeople )
00906
00907
return true;
00908
00909
QString type;
00910
if( incidence->type() ==
"Event") type = i18n(
"event");
00911
else if( incidence->type() ==
"Todo" ) type = i18n(
"task");
00912
else if( incidence->type() ==
"Journal" ) type = i18n(
"journal entry");
00913
else type = incidence->type();
00914
QString txt = i18n(
"This %1 includes other people. "
00915
"Should email be sent out to the attendees?" )
00916 .arg( type );
00917 rc = KMessageBox::questionYesNoCancel( parent, txt,
00918 i18n(
"Group scheduling email") );
00919 }
else if( incidence->type() ==
"Todo" ) {
00920
if( method == Scheduler::Request )
00921
00922 method = Scheduler::Reply;
00923
00924
00925
QString txt = i18n(
"Do you want to send a status update to the "
00926
"organizer of this task?");
00927 rc = KMessageBox::questionYesNo( parent, txt );
00928 }
else if( incidence->type() ==
"Event" ) {
00929
00930
00931
00932
QString txt;
00933
if( isDeleting )
00934 txt = i18n(
"You are not the organizer of this event. "
00935
"Deleting it will bring your calendar out of sync "
00936
"with the organizers calendar. Do you really want "
00937
"to delete it?" );
00938
else
00939 txt = i18n(
"You are not the organizer of this event. "
00940
"Editing it will bring your calendar out of sync "
00941
"with the organizers calendar. Do you really want "
00942
"to edit it?" );
00943 rc = KMessageBox::questionYesNo( parent, txt );
00944
return ( rc == KMessageBox::Yes );
00945 }
else {
00946 qFatal(
"Some unimplemented thing happened" );
00947 }
00948
00949
if( rc == KMessageBox::Yes ) {
00950
00951
00952
if( incidence->summary().isEmpty() )
00953 incidence->setSummary( i18n(
"<No summary given>") );
00954
00955
00956 KCal::MailScheduler scheduler( mCalendar );
00957 scheduler.performTransaction( incidence, method );
00958
00959
return true;
00960 }
else if( rc == KMessageBox::No )
00961
return true;
00962
else
00963
return false;
00964 }
00965
00966
00967
00968
00969
static QString stringProp( KTNEFMessage* tnefMsg,
const Q_UINT32& key,
00970
const QString& fallback = QString::null)
00971 {
00972
return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16,
00973 fallback );
00974 }
00975
00976
static QString sNamedProp( KTNEFMessage* tnefMsg,
const QString& name,
00977
const QString& fallback = QString::null )
00978 {
00979
return tnefMsg->findNamedProp( name, fallback );
00980 }
00981
00982
struct save_tz {
char* old_tz;
char* tz_env_str; };
00983
00984
00985
static struct save_tz set_tz( const char* _tc )
00986 {
00987
const char *tc = _tc?_tc:
"UTC";
00988
00989
struct save_tz rv;
00990
00991 rv.old_tz = 0;
00992 rv.tz_env_str = 0;
00993
00994
00995
00996
char* tz_env = 0;
00997
if( getenv(
"TZ" ) ) {
00998 tz_env = strdup( getenv(
"TZ" ) );
00999 rv.old_tz = tz_env;
01000 }
01001
char* tmp_env = (
char*)malloc( strlen( tc ) + 4 );
01002 strcpy( tmp_env,
"TZ=" );
01003 strcpy( tmp_env+3, tc );
01004 putenv( tmp_env );
01005
01006 rv.tz_env_str = tmp_env;
01007
01008
01009
01010 tzset();
01011
01012
01013
return rv;
01014 }
01015
01016
01017
static void unset_tz(
struct save_tz old_tz )
01018 {
01019
if( old_tz.old_tz ) {
01020
char* tmp_env = (
char*)malloc( strlen( old_tz.old_tz ) + 4 );
01021 strcpy( tmp_env,
"TZ=" );
01022 strcpy( tmp_env+3, old_tz.old_tz );
01023 putenv( tmp_env );
01024
01025 free( old_tz.old_tz );
01026 }
else {
01027
01028 putenv( strdup(
"TZ") );
01029 }
01030 tzset();
01031
01032
01033
if( old_tz.tz_env_str ) free( old_tz.tz_env_str );
01034 }
01035
01036
static QDateTime utc2Local(
const QDateTime& utcdt )
01037 {
01038
struct tm tmL;
01039
01040 save_tz tmp_tz = set_tz(
"UTC");
01041 time_t utc = utcdt.toTime_t();
01042 unset_tz( tmp_tz );
01043
01044 localtime_r( &utc, &tmL );
01045
return QDateTime(
QDate( tmL.tm_year+1900, tmL.tm_mon+1, tmL.tm_mday ),
01046
QTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
01047 }
01048
01049
static QDateTime pureISOToLocalQDateTime(
const QString& dtStr,
01050
bool bDateOnly =
false )
01051 {
01052
QDate tmpDate;
01053
QTime tmpTime;
01054
int year, month, day, hour, minute, second;
01055
01056
if( bDateOnly ) {
01057 year = dtStr.left( 4 ).toInt();
01058 month = dtStr.mid( 4, 2 ).toInt();
01059 day = dtStr.mid( 6, 2 ).toInt();
01060 hour = 0;
01061 minute = 0;
01062 second = 0;
01063 }
else {
01064 year = dtStr.left( 4 ).toInt();
01065 month = dtStr.mid( 4, 2 ).toInt();
01066 day = dtStr.mid( 6, 2 ).toInt();
01067 hour = dtStr.mid( 9, 2 ).toInt();
01068 minute = dtStr.mid( 11, 2 ).toInt();
01069 second = dtStr.mid( 13, 2 ).toInt();
01070 }
01071 tmpDate.setYMD( year, month, day );
01072 tmpTime.setHMS( hour, minute, second );
01073
01074
if( tmpDate.isValid() && tmpTime.isValid() ) {
01075
QDateTime dT =
QDateTime( tmpDate, tmpTime );
01076
01077
if( !bDateOnly ) {
01078
01079
if (dtStr.at(dtStr.length()-1) ==
'Z') {
01080
01081
01082 dT = utc2Local( dT );
01083 }
01084 }
01085
return dT;
01086 }
else
01087
return QDateTime();
01088 }
01089
01090
QString KOGroupware::msTNEFToVPart(
const QByteArray& tnef )
01091 {
01092
bool bOk =
false;
01093
01094 KTNEFParser parser;
01095
QBuffer buf( tnef );
01096 CalendarLocal cal;
01097 KABC::Addressee addressee;
01098 KABC::VCardConverter cardConv;
01099 ICalFormat calFormat;
01100 Event* event =
new Event();
01101
01102
if( parser.openDevice( &buf ) ) {
01103 KTNEFMessage* tnefMsg = parser.message();
01104
01105
01106
01107
01108
QString msgClass = tnefMsg->findProp( 0x001A, QString::null,
true )
01109 .upper();
01110
if( !msgClass.isEmpty() ) {
01111
01112
01113
bool bCompatClassAppointment =
false;
01114
bool bCompatMethodRequest =
false;
01115
bool bCompatMethodCancled =
false;
01116
bool bCompatMethodAccepted =
false;
01117
bool bCompatMethodAcceptedCond =
false;
01118
bool bCompatMethodDeclined =
false;
01119
if( msgClass.startsWith(
"IPM.MICROSOFT SCHEDULE." ) ) {
01120 bCompatClassAppointment =
true;
01121
if( msgClass.endsWith(
".MTGREQ" ) )
01122 bCompatMethodRequest =
true;
01123
if( msgClass.endsWith(
".MTGCNCL" ) )
01124 bCompatMethodCancled =
true;
01125
if( msgClass.endsWith(
".MTGRESPP" ) )
01126 bCompatMethodAccepted =
true;
01127
if( msgClass.endsWith(
".MTGRESPA" ) )
01128 bCompatMethodAcceptedCond =
true;
01129
if( msgClass.endsWith(
".MTGRESPN" ) )
01130 bCompatMethodDeclined =
true;
01131 }
01132
bool bCompatClassNote = ( msgClass ==
"IPM.MICROSOFT MAIL.NOTE" );
01133
01134
if( bCompatClassAppointment ||
"IPM.APPOINTMENT" == msgClass ) {
01135
01136
bool bIsReply =
false;
01137
QString prodID =
"-//Microsoft Corporation//Outlook ";
01138 prodID += tnefMsg->findNamedProp(
"0x8554",
"9.0" );
01139 prodID +=
"MIMEDIR/EN\n";
01140 prodID +=
"VERSION:2.0\n";
01141 calFormat.setApplication(
"Outlook", prodID );
01142
01143 Scheduler::Method method;
01144
if( bCompatMethodRequest )
01145 method = Scheduler::Request;
01146
else if( bCompatMethodCancled )
01147 method = Scheduler::Cancel;
01148
else if( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
01149 bCompatMethodDeclined ) {
01150 method = Scheduler::Reply;
01151 bIsReply =
true;
01152 }
else {
01153
01154
01155
01156
01157
01158
01159
01160
01161
if( tnefMsg->findProp(0x0c17) ==
"1" )
01162 bIsReply =
true;
01163 method = Scheduler::Request;
01164 }
01165
01167 ScheduleMessage schedMsg(event, method, ScheduleMessage::Unknown );
01168
01169
QString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
01170
01171
if( !sSenderSearchKeyEmail.isEmpty() ) {
01172
int colon = sSenderSearchKeyEmail.find(
':' );
01173
01174
if( sSenderSearchKeyEmail.find(
':' ) == -1 )
01175 sSenderSearchKeyEmail.remove( 0, colon+1 );
01176 }
01177
01178
QString s( tnefMsg->findProp( 0x0e04 ) );
01179
QStringList attendees = QStringList::split(
';', s );
01180
if( attendees.count() ) {
01181
for( QStringList::Iterator it = attendees.begin();
01182 it != attendees.end(); ++it ) {
01183
01184
01185
if( (*it).find(
'@') == -1 ) {
01186 s = (*it).stripWhiteSpace();
01187
01188 Attendee *attendee =
new Attendee( s, s,
true );
01189
if( bIsReply ) {
01190
if( bCompatMethodAccepted )
01191 attendee->setStatus( Attendee::Accepted );
01192
if( bCompatMethodDeclined )
01193 attendee->setStatus( Attendee::Declined );
01194
if( bCompatMethodAcceptedCond )
01195 attendee->setStatus(Attendee::Tentative);
01196 }
else {
01197 attendee->setStatus( Attendee::NeedsAction );
01198 attendee->setRole( Attendee::ReqParticipant );
01199 }
01200 event->addAttendee(attendee);
01201 }
01202 }
01203 }
else {
01204
01205
01206 s = sSenderSearchKeyEmail;
01207
if( !s.isEmpty() ) {
01208 Attendee *attendee =
new Attendee( QString::null, QString::null,
01209
true );
01210
if( bIsReply ) {
01211
if( bCompatMethodAccepted )
01212 attendee->setStatus( Attendee::Accepted );
01213
if( bCompatMethodAcceptedCond )
01214 attendee->setStatus( Attendee::Declined );
01215
if( bCompatMethodDeclined )
01216 attendee->setStatus( Attendee::Tentative );
01217 }
else {
01218 attendee->setStatus(Attendee::NeedsAction);
01219 attendee->setRole(Attendee::ReqParticipant);
01220 }
01221 event->addAttendee(attendee);
01222 }
01223 }
01224 s = tnefMsg->findProp( 0x0c1f );
01225
if( s.isEmpty() && !bIsReply )
01226 s = sSenderSearchKeyEmail;
01227
if( !s.isEmpty() )
01228 event->setOrganizer( s );
01229
01230 s = tnefMsg->findProp( 0x8516 ).replace(
QChar(
'-' ), QString::null )
01231 .replace(
QChar(
':' ), QString::null );
01232 event->setDtStart( QDateTime::fromString( s ) );
01233
01234 s = tnefMsg->findProp( 0x8517 ).replace(
QChar(
'-' ), QString::null )
01235 .replace(
QChar(
':' ), QString::null );
01236 event->setDtEnd( QDateTime::fromString( s ) );
01237
01238 s = tnefMsg->findProp( 0x8208 );
01239 event->setLocation( s );
01240
01241
01242
01243
01244
01245
01246 s = tnefMsg->findProp( 0x0023 );
01247 event->setUid( s );
01248
01249
01250
01251
01252 s = tnefMsg->findProp( 0x8202 ).replace(
QChar(
'-' ), QString::null )
01253 .replace(
QChar(
':' ), QString::null );
01254
01255
01256
01257 s = tnefMsg->findNamedProp(
"Keywords" );
01258 event->setCategories( s );
01259
01260 s = tnefMsg->findProp( 0x1000 );
01261 event->setDescription( s );
01262
01263 s = tnefMsg->findProp( 0x0070 );
01264 event->setSummary( s );
01265
01266 s = tnefMsg->findProp( 0x0026 );
01267 event->setPriority( s.toInt() );
01268
01269
01270
if(!tnefMsg->findProp(0x8503).isEmpty()) {
01271 Alarm *alarm =
new Alarm(event);
01272
QDateTime highNoonTime =
01273 pureISOToLocalQDateTime( tnefMsg->findProp( 0x8502 )
01274 .replace(
QChar(
'-' ),
"" )
01275 .replace(
QChar(
':' ),
"" ) );
01276
QDateTime wakeMeUpTime =
01277 pureISOToLocalQDateTime( tnefMsg->findProp( 0x8560,
"" )
01278 .replace(
QChar(
'-' ),
"" )
01279 .replace(
QChar(
':' ),
"" ) );
01280 alarm->setTime(wakeMeUpTime);
01281
01282
if( highNoonTime.isValid() && wakeMeUpTime.isValid() )
01283 alarm->setStartOffset( Duration( highNoonTime, wakeMeUpTime ) );
01284
else
01285
01286 alarm->setStartOffset( Duration( 15*60 ) );
01287 alarm->setDisplayAlarm( i18n(
"Reminder" ) );
01288
01289
01290
01291 event->addAlarm( alarm );
01292 }
01293 cal.addEvent( event );
01294 bOk =
true;
01295
01296 }
else if( bCompatClassNote ||
"IPM.CONTACT" == msgClass ) {
01297 addressee.setUid( stringProp( tnefMsg, attMSGID ) );
01298 addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
01299 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ),
true );
01300 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ),
false );
01301 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ),
false );
01302 addressee.insertCustom(
"KADDRESSBOOK",
"X-IMAddress", sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
01303 addressee.insertCustom(
"KADDRESSBOOK",
"X-SpousesName", stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
01304 addressee.insertCustom(
"KADDRESSBOOK",
"X-ManagersName", stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
01305 addressee.insertCustom(
"KADDRESSBOOK",
"X-AssistantsName", stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
01306 addressee.insertCustom(
"KADDRESSBOOK",
"X-Department", stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
01307 addressee.insertCustom(
"KADDRESSBOOK",
"X-Office", stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
01308 addressee.insertCustom(
"KADDRESSBOOK",
"X-Profession", stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
01309
01310
QString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY )
01311 .replace(
QChar(
'-' ), QString::null )
01312 .replace(
QChar(
':' ), QString::null );
01313
if( !s.isEmpty() )
01314 addressee.insertCustom(
"KADDRESSBOOK",
"X-Anniversary", s );
01315
01316 addressee.setUrl( KURL( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
01317
01318
01319 addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
01320 addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
01321 addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
01322 addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
01323 addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
01324
01325 addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
01326 addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
01327 addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
01328
01329
01330
01331
01332
01333 KABC::Address adr;
01334 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
01335 adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
01336 adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
01337 adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
01338 adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
01339 adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
01340 adr.setType(KABC::Address::Home);
01341 addressee.insertAddress(adr);
01342
01343 adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
01344 adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
01345 adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
01346 adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
01347 adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
01348 adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
01349 adr.setType( KABC::Address::Work );
01350 addressee.insertAddress( adr );
01351
01352 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
01353 adr.setStreet( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
01354 adr.setLocality( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
01355 adr.setRegion( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
01356 adr.setPostalCode( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
01357 adr.setCountry( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
01358 adr.setType( KABC::Address::Dom );
01359 addressee.insertAddress(adr);
01360
01361
01362
01363
01364
01365
QString nr;
01366 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
01367 addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Home ) );
01368 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
01369 addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Work ) );
01370 nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
01371 addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Cell ) );
01372 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
01373 addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) );
01374 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
01375 addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ) );
01376
01377 s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY )
01378 .replace(
QChar(
'-' ), QString::null )
01379 .replace(
QChar(
':' ), QString::null );
01380
if( !s.isEmpty() )
01381 addressee.setBirthday( QDateTime::fromString( s ) );
01382
01383 bOk = ( !addressee.isEmpty() );
01384 }
else if(
"IPM.NOTE" == msgClass ) {
01385
01386 }
01387 }
01388 }
01389
01390
01391
QString iCal = calFormat.toString( &cal );
01392
if( !iCal.isEmpty() )
01393
01394
return iCal;
01395
01396
01397 KABC::VCardConverter converter;
01398
return converter.createVCard( addressee );
01399 }
01400
01401
01402
#include "kogroupware.moc"