summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--korganizer/mainwindow.cpp21
-rw-r--r--libkcal/phoneformat.cpp60
-rw-r--r--libkcal/phoneformat.h2
-rw-r--r--libkcal/vcalformat.cpp19
-rw-r--r--libkcal/vcalformat.h2
5 files changed, 52 insertions, 52 deletions
diff --git a/korganizer/mainwindow.cpp b/korganizer/mainwindow.cpp
index cce182a..6c0aa9b 100644
--- a/korganizer/mainwindow.cpp
+++ b/korganizer/mainwindow.cpp
@@ -816,515 +816,534 @@ void MainWindow::initActions()
if (!p-> mShowIconStretch)
iconToolBar->setStretchableWidget ( dummy ) ;
else
configureToolBarMenu->setItemChecked( 5, true );
if (p-> mShowIconWhatsThis)
QWhatsThis::whatsThisButton ( iconToolBar );
connect( configureToolBarMenu, SIGNAL( activated( int ) ),this, SLOT(configureToolBar( int ) ) );
configureAgenda( p->mHourSize );
connect( configureAgendaMenu, SIGNAL( activated( int ) ),this, SLOT(configureAgenda( int ) ) );
}
void MainWindow::fillSyncMenu()
{
syncMenu->clear();
syncMenu->insertItem( i18n("Configure..."), 0 );
syncMenu->insertSeparator();
syncMenu->insertItem( i18n("Multiple sync"), 1 );
syncMenu->insertSeparator();
KConfig config ( locateLocal( "config","syncprofilesrc" ) );
config.setGroup("General");
QStringList prof = config.readListEntry("SyncProfileNames");
KOPrefs::instance()->mLocalMachineName = config.readEntry("LocalMachineName","undefined");
if ( prof.count() < 3 ) {
prof.clear();
prof << i18n("Sharp_DTM");
prof << i18n("Local_file");
prof << i18n("Last_file");
KSyncProfile* temp = new KSyncProfile ();
temp->setName( prof[0] );
temp->writeConfig(&config);
temp->setName( prof[1] );
temp->writeConfig(&config);
temp->setName( prof[2] );
temp->writeConfig(&config);
config.setGroup("General");
config.writeEntry("SyncProfileNames",prof);
config.writeEntry("ExternSyncProfiles","Sharp_DTM");
config.sync();
delete temp;
}
KOPrefs::instance()->mExternSyncProfiles = config.readListEntry("ExternSyncProfiles");
KOPrefs::instance()->mSyncProfileNames = prof;
int i;
for ( i = 0; i < prof.count(); ++i ) {
syncMenu->insertItem( prof[i], 1000+i );
if ( i == 2 )
syncMenu->insertSeparator();
}
QDir app_dir;
if ( !app_dir.exists(QDir::homeDirPath()+"/Applications/dtm" ) ) {
syncMenu->setItemEnabled( false , 1000 );
}
mView->setupExternSyncProfiles();
}
int MainWindow::ringSync()
{
int syncedProfiles = 0;
int i;
QTime timer;
KConfig config ( locateLocal( "config","syncprofilesrc" ) );
QStringList syncProfileNames = KOPrefs::instance()->mSyncProfileNames;
KSyncProfile* temp = new KSyncProfile ();
KOPrefs::instance()->mAskForPreferences = false;
for ( i = 0; i < syncProfileNames.count(); ++i ) {
mCurrentSyncProfile = i;
temp->setName(syncProfileNames[mCurrentSyncProfile]);
temp->readConfig(&config);
if ( temp->getIncludeInRingSync() && ( i < 1 || i > 2 )) {
setCaption(i18n("Profile ")+syncProfileNames[mCurrentSyncProfile]+ i18n(" is synced ... "));
++syncedProfiles;
// KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences();
KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile();
KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting();
KOPrefs::instance()->mShowSyncSummary = false;
mView->setSyncDevice(syncProfileNames[i] );
mView->setSyncName( KOPrefs::instance()->mLocalMachineName );
if ( i == 0 ) {
syncSharp();
} else {
if ( temp->getIsLocalFileSync() ) {
if ( syncWithFile( temp->getRemoteFileName( ), true ) )
KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName();
} else {
if ( temp->getIsPhoneSync() ) {
KOPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ;
KOPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( );
KOPrefs::instance()->mPhoneModel = temp->getPhoneModel( );
syncPhone();
} else
syncRemote( temp, false );
}
}
timer.start();
setCaption(i18n("Multiple sync in progress ... please wait!") );
while ( timer.elapsed () < 2000 ) {
qApp->processEvents();
#ifndef _WIN32_
sleep (1);
#endif
}
}
}
delete temp;
return syncedProfiles;
}
void MainWindow::multiSync( bool askforPrefs )
{
if (mBlockSaveFlag)
return;
mBlockSaveFlag = true;
QString question = i18n("Do you really want\nto multiple sync\nwith all checked profiles?\nSyncing takes some\ntime - all profiles\nare synced twice!");
if ( QMessageBox::information( this, i18n("KO/Pi Sync"),
question,
i18n("Yes"), i18n("No"),
0, 0 ) != 0 ) {
mBlockSaveFlag = false;
setCaption(i18n("Aborted! Nothing synced!"));
return;
}
mView->setSyncDevice(i18n("Multiple profiles") );
KOPrefs::instance()->mSyncAlgoPrefs = KOPrefs::instance()->mRingSyncAlgoPrefs;
if ( askforPrefs ) {
mView->edit_sync_options();
KOPrefs::instance()->mRingSyncAlgoPrefs = KOPrefs::instance()->mSyncAlgoPrefs;
}
setCaption(i18n("Multiple sync started.") );
qApp->processEvents();
int num = ringSync() ;
if ( num > 1 )
ringSync();
mBlockSaveFlag = false;
if ( num )
save();
if ( num )
setCaption(i18n("%1 profiles synced. Multiple sync completed!").arg(num) );
else
setCaption(i18n("Nothing synced! No profiles defined for multisync!"));
return;
}
void MainWindow::slotSyncMenu( int action )
{
//qDebug("syncaction %d ", action);
if ( action == 0 ) {
confSync();
return;
}
if ( action == 1 ) {
multiSync( true );
return;
}
if (mBlockSaveFlag)
return;
mBlockSaveFlag = true;
mCurrentSyncProfile = action - 1000 ;
mView->setSyncDevice(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile] );
mView->setSyncName( KOPrefs::instance()->mLocalMachineName );
KConfig config ( locateLocal( "config","syncprofilesrc" ) );
KSyncProfile* temp = new KSyncProfile ();
temp->setName(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]);
temp->readConfig(&config);
KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences();
KOPrefs::instance()->mSyncAlgoPrefs = temp->getSyncPrefs();
KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile();
KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting();
KOPrefs::instance()->mShowSyncSummary = temp->getShowSummaryAfterSync();
if ( action == 1000 ) {
syncSharp();
} else if ( action == 1001 ) {
syncLocalFile();
} else if ( action == 1002 ) {
quickSyncLocalFile();
} else if ( action >= 1003 ) {
if ( temp->getIsLocalFileSync() ) {
if ( syncWithFile( temp->getRemoteFileName( ), false ) )
KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName();
} else {
if ( temp->getIsPhoneSync() ) {
KOPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ;
KOPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( );
KOPrefs::instance()->mPhoneModel = temp->getPhoneModel( );
syncPhone();
} else
syncRemote( temp );
}
}
delete temp;
mBlockSaveFlag = false;
}
void MainWindow::setDefaultPreferences()
{
KOPrefs *p = KOPrefs::instance();
p->mCompactDialogs = true;
p->mConfirm = true;
// p->mEnableQuickTodo = false;
}
QString MainWindow::resourcePath()
{
return KGlobal::iconLoader()->iconPath();
}
void MainWindow::displayText( QString text ,QString cap )
{
QDialog dia( this, "name", true ); ;
dia.setCaption( cap );
QVBoxLayout* lay = new QVBoxLayout( &dia );
lay->setSpacing( 3 );
lay->setMargin( 3 );
QTextBrowser tb ( &dia );
lay->addWidget( &tb );
tb.setText( text );
#ifdef DESKTOP_VERSION
dia.resize( 640, 480);
#else
dia.showMaximized();
#endif
dia.exec();
}
void MainWindow::displayFile( QString fn, QString cap )
{
QString fileName = resourcePath() + fn;
QString text;
QFile file( fileName );
if (!file.open( IO_ReadOnly ) ) {
return ;
}
QTextStream ts( &file );
text = ts.read();
file.close();
displayText( text, cap);
}
void MainWindow::features()
{
displayFile( "featuresKOPI.txt",i18n("KO/Pi Features and hints") );
}
void MainWindow::usertrans()
{
displayFile( "usertranslationHOWTO.txt",i18n("KO/Pi User translation HowTo") );
}
+#if 0
+#include <libkcal/vcalformat.h>
+#include <libkcal/event.h>
+#include <libkcal/todo.h>
+#include <libkcal/incidence.h>
+#endif
void MainWindow::synchowto()
{
-
+#if 0
+ QPtrList<Incidence> er = mCalendar->rawIncidences();
+ Incidence* inR = er.first();
+ VCalFormat vf;
+ QString strout;
+ while ( inR ) {
+ if ( inR->type() == "Todo" )
+ strout = vf.todoToString( (Todo *) inR );
+ if ( inR->type() == "Event" )
+ strout = vf.eventToString( (Event *) inR );
+ qDebug("incidence: \n%s\n ente\n\n",strout.latin1() );
+ inR = er.next();
+ }
+#endif
displayFile( "howtoSYNC.txt",i18n("KO/Pi Synchronization HowTo") );
}
void MainWindow::faq()
{
displayFile( "kopiFAQ.txt",i18n("KO/Pi FAQ") );
}
void MainWindow::whatsNew()
{
displayFile( "kopiWhatsNew.txt",i18n("KO/Pi Version Info") );
}
void MainWindow::licence()
{
KApplication::showLicence();
}
void MainWindow::about()
{
QString version;
#include <../version>
QMessageBox::about( this, i18n("About KOrganizer/Pi"),
i18n("KOrganizer/Platform-independent\n") +
"(KO/Pi) " + version + " - " +
#ifdef DESKTOP_VERSION
i18n("Desktop Edition\n") +
#else
i18n("PDA-Edition\nfor: Zaurus 5x00 / 7x0 / 8x0\n") +
#endif
i18n("(c) 2004 Lutz Rogowski\nEmail:lutz@pi-sync.net\nKO/Pi is based on KOrganizer\n(c) 2002,2003 Cornelius Schumacher\nEmail: schumacher@kde.org\nKOrganizer/Pi is licensed\nunder the GPL.\nKO/Pi can be compiled for\nLinux, Zaurus-PDA and Windows\nwww.korganizer.org\nwww.pi-sync.net\n") );
}
void MainWindow::keyBindings()
{
QString cap = i18n("Key bindings KOrganizer/Pi");
QString text = i18n("<p><h2>KO/Pi key shortcuts:</h2></p>\n") +
i18n("<p><b>H</b>: This help dialog | <b>S</b>: Search dialog</p>\n")+
i18n("<p><b>I</b>: Show info for selected event/todo</p>\n") +
i18n("<p><b>Space</b>: Toggle fullscreen | <b>P</b>: Date picker</p>\n")+
i18n("<p><b>F</b>: Toggle filterview |<b>F+ctrl</b>: Edit filter </p>\n")+
i18n("<p><b>O</b>: Filter On/Off | <b>J</b>: Journal view</p>\n")+
i18n("<p><b>1-0</b> (+<b>ctrl</b>): Select filter 1-10 (11-20)</p>\n")+
i18n("<p><b>N</b>: Next days view| <b>W</b>: What's next view\n ")+
i18n("<p><b>V</b>: Todo view | <b>L</b>: Event list view</p>\n")+
i18n("<p><b>Z,Y</b>: Work week view | <b>U</b>: Week view</p>\n")+
i18n("<p><b>D</b>: One day view | <b>M</b>: Month view</p>\n")+
i18n("<p><b>E</b>: Edit selected item |<b> E+ctrl</b>: New Event</p>\n")+
i18n("<p><b>T</b>: Goto today | <b>T+ctrl</b>: New Todo</p>\n")+
i18n("<p><b>S+ctrl</b>: Add sub-todo | <b>X</b>: Toggle datenavigator</p>\n")+
i18n("<p><b>+,-</b> : Zoom in/out agenda | <b>A</b>: Toggle allday agenda height</p>\n")+
i18n("<p><b>C</b>: Show current time in agenda view</p>\n")+
i18n("<p><b>B</b>: Edit description (details) of selected item</p>\n")+
i18n("<p><b>right</b>: Next week | <b>right+ctrl</b>: Next month</p>\n")+
i18n("<p><b>left</b>: Prev. week | <b>left+ctrl</b>: Prev. month</p>\n")+
i18n("<p><b>del,backspace</b>: Delete selected item</p>\n")+
i18n("<p><h3>In agenda view:</h3></p>\n") +
i18n("<p><b>up/down</b>: Scroll agenda view</p>\n")+
i18n("<p><b>ctrl+up/down</b>: Scroll small todo view</p>\n")+
i18n("<p><h3>In todo view:</h3></p>\n") +
i18n("<p><b>Q</b>: Toggle quick todo line edit.</p>\n")+
i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+
i18n("<p><b>return</b>: Mark item as completed+one step down.</p>\n")+
i18n("<p><b>return+shift</b>: Mark item as not completed+one step down</p>\n")+
i18n("<p><h3>In list view:</h3></p>\n") +
i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+
i18n("<p><b>return</b>: Select item+one step down</p>\n")+
i18n("<p><b>return+shift</b>: Deselect item+one step down</p>\n")+
i18n("<p><b>up/down</b>: Next/prev item</p>\n")+
i18n("<p><b>ctrl+up/down</b>: Goto up/down by 20% of items</p>\n")+
i18n("<p><b>shift+up/down</b>: Goto first/last item</p>\n")+
i18n("<p><h3>In event/todo viewer:</h3></p>\n") +
i18n("<p><b>I,C</b>: Close dialog.</p>\n")+
i18n("<p><b>A</b>: Show agenda view.</p>\n")+
i18n("<p><b>E</b>: Edit item</p>\n") +
i18n("<p><h2>KO/Pi icon colors:</h2></p>\n") +
i18n("<p><b>(for square icons in agenda and month view)</b></p>\n") +
i18n("<p><b>Cross</b>: Item cancelled.([c] in Whats'Next view)</p>\n")+
i18n("<p><b>Red</b>: Alarm set.([a] in Whats'Next view)</p>\n")+
i18n("<p><b>Blue</b>: Recurrent event.([r] in Whats'Next view)</p>\n")+
i18n("<p><b>Dark green</b>: Information(description) available.([i] in WN view)</p>\n")+
i18n("<p><b>Black</b>: Event/todo with attendees. You are the organizer!</p>\n")+
i18n("<p><b>Dark yellow</b>: Event/todo with attendees.</p>\n") +
i18n("<p><b>White</b>: Item readonly</p>\n");
displayText( text, cap);
}
void MainWindow::aboutAutoSaving()
{
QMessageBox* msg;
msg = new QMessageBox( i18n("Auto Saving in KOrganizer/Pi"),
i18n("After changing something, the data is\nautomatically saved to the file\n~/kdepim/apps/korganizer/mycalendar.ics\nafter (configureable) three minutes.\nFor safety reasons there is one autosaving\nafter 10 minutes (of idle time) again. The \ndata is saved automatically when closing KO/Pi\nYou can create a backup file \nwith: File - Save Calendar Backup\n"), QMessageBox::NoIcon,
QMessageBox::Ok,
QMessageBox::NoButton,
QMessageBox::NoButton);
msg->exec();
delete msg;
}
void MainWindow::aboutKnownBugs()
{
QMessageBox* msg;
msg = new QMessageBox( i18n("Known Problems in KOrganizer/Pi"),
i18n("1) Importing *.vcs or *.ics files from\nother applications may not work properly,\nif there are events with properties\nKO/Pi does not support.\n")+
i18n("2) Audio alarm daemon\nfor Zaurus is available!\nas an additional small application\n")+
i18n("\nPlease report unexpected behaviour to\nlutz@pi-sync.net\n") +
i18n("\nor report them in the bugtracker on\n") +
i18n("\nhttp://sourceforge.net/projects/kdepimpi\n"),
QMessageBox::NoIcon,
QMessageBox::Ok,
QMessageBox::NoButton,
QMessageBox::NoButton);
msg->exec();
delete msg;
}
QString MainWindow::defaultFileName()
{
return locateLocal( "data", "korganizer/mycalendar.ics" );
}
void MainWindow::processIncidenceSelection( Incidence *incidence )
{
if ( !incidence ) {
enableIncidenceActions( false );
mNewSubTodoAction->setEnabled( false );
setCaptionToDates();
return;
}
//KGlobal::locale()->formatDateTime(nextA, true);
QString startString = "";
if ( incidence->type() != "Todo" ) {
if ( incidence->dtStart().date() < incidence->dtEnd().date() ) {
if ( incidence->doesFloat() ) {
startString += ": "+incidence->dtStartDateStr( true );
startString += " --- "+((Event*)incidence)->dtEndDateStr( true );
} else {
startString = ": "+incidence->dtStartStr(true);
startString += " --- "+((Event*)incidence)->dtEndStr(true);
}
} else {
if ( incidence->dtStart().time() != incidence->dtEnd().time() )
startString = ": "+KGlobal::locale()->formatTime(incidence->dtStart().time())+
"-"+KGlobal::locale()->formatTime(incidence->dtEnd().time());
startString +=" "+KGlobal::locale()->formatDate( incidence->dtStart().date(), true);
}
}
else
startString = i18n(": (Prio ") +QString::number( (( KCal::Todo*)incidence)->priority() ) +") "+QString::number( (( KCal::Todo*)incidence)->percentComplete() ) +i18n("\% completed");
if ( !incidence->location().isEmpty() )
startString += " (" +incidence->location()+")";
setCaption( incidence->summary()+startString);
enableIncidenceActions( true );
if ( incidence->type() == "Event" ) {
mShowAction->setText( i18n("Show Event...") );
mEditAction->setText( i18n("Edit Event...") );
mDeleteAction->setText( i18n("Delete Event...") );
mNewSubTodoAction->setEnabled( false );
} else if ( incidence->type() == "Todo" ) {
mShowAction->setText( i18n("Show Todo...") );
mEditAction->setText( i18n("Edit Todo...") );
mDeleteAction->setText( i18n("Delete Todo...") );
mNewSubTodoAction->setEnabled( true );
} else {
mShowAction->setText( i18n("Show...") );
mShowAction->setText( i18n("Edit...") );
mShowAction->setText( i18n("Delete...") );
mNewSubTodoAction->setEnabled( false );
}
}
void MainWindow::enableIncidenceActions( bool enabled )
{
mShowAction->setEnabled( enabled );
mEditAction->setEnabled( enabled );
mDeleteAction->setEnabled( enabled );
}
void MainWindow::importOL()
{
#ifdef _WIN32_
KOImportOLdialog *id = new KOImportOLdialog("Import from OL - select folder!" , mView->calendar(),this );
id->exec();
delete id;
mView->updateView();
#endif
}
void MainWindow::importBday()
{
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
i18n("When importing birthdays twice\nduplicated events will be ignored,\nif the event has not been\nchanged in KO/Pi!\n"),
i18n("Import!"), i18n("Cancel"), 0,
0, 1 );
if ( result == 0 ) {
mView->importBday();
}
}
void MainWindow::importQtopia()
{
#ifndef DESKTOP_VERSION
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
i18n("When importing a calendar twice\nduplicated events will be ignored!\nYou can create a backup file with\nFile - Save Calendar Backup\nto revert importing"),
i18n("Import!"), i18n("Cancel"), 0,
0, 1 );
if ( result == 0 ) {
QString datebook = Global::applicationFileName( "datebook", "datebook.xml");
QString todolist = Global::applicationFileName( "todolist", "todolist.xml");
QString categories = QString( getenv( "HOME" ) ) + "/Settings/Categories.xml";
mView->importQtopia( categories, datebook, todolist );
}
#else
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
i18n("Not supported \non desktop!\n"),
i18n("Ok"), i18n("Cancel"), 0,
0, 1 );
#endif
}
void MainWindow::saveOnClose()
{
KOPrefs *p = KOPrefs::instance();
p->mToolBarHor = ( iconToolBar->orientation () == Qt:: Horizontal );
p->mToolBarUp = iconToolBar->x() > width()/2 ||
iconToolBar->y() > height()/2;
mView->writeSettings();
if ( mCalendarModifiedFlag || mView->checkFileChanged( defaultFileName()))
save();
}
void MainWindow::slotModifiedChanged( bool changed )
{
if ( mBlockAtStartup )
return;
int msec;
// we store the changes after 1 minute,
// and for safety reasons after 10 minutes again
if ( !mBlockSaveFlag )
msec = (1000 * 60*KOPrefs::instance()->mAutoSaveInterval) +1000;
else
msec = 1000 * 600;
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp
index 11c68c5..e6d4879 100644
--- a/libkcal/phoneformat.cpp
+++ b/libkcal/phoneformat.cpp
@@ -617,565 +617,523 @@ ulong PhoneFormat::getCsumTodo( Todo* todo )
completedString = "yes";
attList << completedString;
attList << QString::number( todo->priority() );
QString alarmString = "na";
Alarm *alarm;
if ( todo->alarms().count() > 0 ) {
alarm = todo->alarms().first();
if ( alarm->enabled() ) {
alarmString = QString::number(alarm->startOffset().asSeconds() );
}
}
attList << alarmString;
attList << todo->categoriesStr();
attList << todo->secrecyStr();
return PhoneFormat::getCsum(attList );
}
ulong PhoneFormat::getCsumEvent( Event* event )
{
QStringList attList;
attList << PhoneParser::dtToString ( event->dtStart() );
attList << PhoneParser::dtToString ( event->dtEnd() );
attList << event->summary();
attList << event->location();
QString alarmString = "na";
Alarm *alarm;
if ( event->alarms().count() > 0 ) {
alarm = event->alarms().first();
if ( alarm->enabled() ) {
alarmString = QString::number( alarm->startOffset().asSeconds() );
}
}
attList << alarmString;
Recurrence* rec = event->recurrence();
QStringList list;
bool writeEndDate = false;
switch ( rec->doesRecur() )
{
case Recurrence::rDaily: // 0
list.append( "0" );
list.append( QString::number( rec->frequency() ));//12
list.append( "0" );
list.append( "0" );
writeEndDate = true;
break;
case Recurrence::rWeekly:// 1
list.append( "1" );
list.append( QString::number( rec->frequency()) );//12
list.append( "0" );
{
int days = 0;
QBitArray weekDays = rec->days();
int i;
for( i = 1; i <= 7; ++i ) {
if ( weekDays[i-1] ) {
days += 1 << (i-1);
}
}
list.append( QString::number( days ) );
}
//pending weekdays
writeEndDate = true;
break;
case Recurrence::rMonthlyPos:// 2
list.append( "2" );
list.append( QString::number( rec->frequency()) );//12
writeEndDate = true;
{
int count = 1;
QPtrList<Recurrence::rMonthPos> rmp;
rmp = rec->monthPositions();
if ( rmp.first()->negative )
count = 5 - rmp.first()->rPos - 1;
else
count = rmp.first()->rPos - 1;
list.append( QString::number( count ) );
}
list.append( "0" );
break;
case Recurrence::rMonthlyDay:// 3
list.append( "3" );
list.append( QString::number( rec->frequency()) );//12
list.append( "0" );
list.append( "0" );
writeEndDate = true;
break;
case Recurrence::rYearlyMonth://4
list.append( "4" );
list.append( QString::number( rec->frequency()) );//12
list.append( "0" );
list.append( "0" );
writeEndDate = true;
break;
default:
list.append( "255" );
list.append( QString() );
list.append( "0" );
list.append( QString() );
list.append( "0" );
list.append( "20991231T000000" );
break;
}
if ( writeEndDate ) {
if ( rec->endDate().isValid() ) { // 15 + 16
list.append( "1" );
list.append( PhoneParser::dtToString( rec->endDate()) );
} else {
list.append( "0" );
list.append( "20991231T000000" );
}
}
attList << list.join("");
attList << event->categoriesStr();
attList << event->secrecyStr();
return PhoneFormat::getCsum(attList );
}
ulong PhoneFormat::getCsum( const QStringList & attList)
{
int max = attList.count() -1;
ulong cSum = 0;
int j,k,i;
int add;
for ( i = 1; i < max ; ++i ) {
QString s = attList[i];
if ( ! s.isEmpty() ){
j = s.length();
for ( k = 0; k < j; ++k ) {
int mul = k +1;
add = s[k].unicode ();
if ( k < 16 )
mul = mul * mul;
add = add * mul *i*i*i;
cSum += add;
}
}
}
return cSum;
}
//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum);
#include <stdlib.h>
#define DEBUGMODE false
bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal)
{
GSM_StateMachine s;
qDebug(" load ");
s.opened = false;
s.msg = NULL;
s.ConfigNum = 0;
QLabel status ( i18n("Reading data. Opening device ..."), 0 );
int w = status.sizeHint().width()+20 ;
if ( w < 200 ) w = 200;
int h = status.sizeHint().height()+20 ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
status.setCaption(i18n("Reading Phone Data") );
status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
status.show();
status.raise();
qApp->processEvents();
#if 0
static char *cp;
static INI_Section *cfg = NULL;
cfg=GSM_FindGammuRC();
int i;
for (i = 0; i <= MAX_CONFIG_NUM; i++) {
if (cfg!=NULL) {
cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false);
if (cp) di.coding = cp;
s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false);
if (s.Config[i].Localize) {
s.msg=INI_ReadFile(s.Config[i].Localize, true);
} else {
#if !defined(WIN32) && defined(LOCALE_PATH)
locale = setlocale(LC_MESSAGES, NULL);
if (locale != NULL) {
snprintf(locale_file, 200, "%s/gammu_%c%c.txt",
LOCALE_PATH,
tolower(locale[0]),
tolower(locale[1]));
s.msg = INI_ReadFile(locale_file, true);
}
#endif
}
}
/* Wanted user specific configuration? */
if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break;
s.ConfigNum++;
/* We want to use only one file descriptor for global and state machine debug output */
s.Config[i].UseGlobalDebugFile = true;
/* We wanted to read just user specified configuration. */
{break;}
}
#endif
int error=initDevice(&s);
qDebug("GSM Init %d (no error is %d)", error, ERR_NONE);
if ( error != ERR_NONE )
return false;
GSM_Phone_Functions *Phone;
GSM_CalendarEntry note;
bool start = true;
Phone=s.Phone.Functions;
bool gshutdown = false;
PhoneParser handler( calendar, mProfileName );
int ccc = 0;
QString message = i18n("Processing event # ");
int procCount = 0;
qDebug("Debug: only 10 calender items are downloaded ");
while (!gshutdown && ccc++ < 10) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
qDebug("readEvent %d ", ccc);
error=Phone->GetNextCalendar(&s,&note,start);
if (error == ERR_EMPTY) break;
start = false;
handler.readEvent( existingCal, &note );
}
start = true;
GSM_ToDoEntry ToDo;
ccc = 0;
message = i18n("Processing todo # ");
procCount = 0;
while (!gshutdown) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
error = Phone->GetNextToDo(&s, &ToDo, start);
if (error == ERR_EMPTY) break;
start = false;
qDebug("ReadTodo %d ", ++ccc);
handler.readTodo( existingCal, &ToDo, &s);
}
error=GSM_TerminateConnection(&s);
return true;
}
void PhoneFormat::event2GSM( Event* ev, GSM_CalendarEntry*Note )
{
-
+ QString eText = vfconverter.eventToString( ev );
+ int pos = 0;
+ GSM_ToDoEntry dummy;
+ GSM_DecodeVCALENDAR_VTODO( (unsigned char*)eText.latin1(), &pos, Note , &dummy, Nokia_VCalendar, Nokia_VToDo );
}
-void PhoneFormat::todo2GSM( Todo* todo, GSM_ToDoEntry *gsm )
+void PhoneFormat::todo2GSM( Todo* todo, GSM_ToDoEntry *gsmTodo )
{
-#if 0
- QStringList list;
- list.append( QString::number( todo->zaurusId() ) );
- list.append( todo->categories().join(",") );
-
- if ( todo->hasStartDate() ) {
- list.append( dtToString( todo->dtStart()) );
- } else
- list.append( QString() );
-
- if ( todo->hasDueDate() ) {
- QTime tim;
- if ( todo->doesFloat()) {
- list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ;
- } else {
- list.append( dtToString(todo->dtDue() ) );
- }
- } else
- list.append( QString() );
-
- if ( todo->isCompleted() ) {
- list.append( dtToString( todo->completed()) );
- list.append( "0" ); // yes 0 == completed
- } else {
- list.append( dtToString( todo->completed()) );
- list.append( "1" );
- }
- list.append( QString::number( todo->priority() ));
- if( ! todo->summary().isEmpty() )
- list.append( todo->summary() );
- else
- list.append( "" );
- if (! todo->description().isEmpty() )
- list.append( todo->description() );
- else
- list.append( "" );
- for(QStringList::Iterator it=list.begin();
- it!=list.end(); ++it){
- QString& s = (*it);
- s.replace(QRegExp("\""), "\"\"");
- if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
- s.prepend('\"');
- s.append('\"');
- } else if(s.isEmpty() && !s.isNull()){
- s = "\"\"";
- }
- }
- return list.join(",");
-#endif
+ QString tText = vfconverter.todoToString( todo );
+ int pos = 0;
+ GSM_CalendarEntry dummy;
+ GSM_DecodeVCALENDAR_VTODO( (unsigned char*)tText.latin1(), &pos, &dummy, gsmTodo, Nokia_VCalendar, Nokia_VToDo );
}
void PhoneFormat::afterSave( Incidence* inc)
{
uint csum;
if ( inc->type() == "Event")
csum = PhoneFormat::getCsumEvent( (Event*) inc );
else
csum = PhoneFormat::getCsumTodo( (Todo*) inc );
inc->setCsum( mProfileName, QString::number( csum ));
inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID );
}
bool PhoneFormat::save( Calendar *calendar)
{
GSM_StateMachine s;
qDebug(" save ");
s.opened = false;
s.msg = NULL;
s.ConfigNum = 0;
QLabel status ( i18n("Writing data. Opening device ..."), 0 );
int w = status.sizeHint().width()+20 ;
if ( w < 200 ) w = 200;
int h = status.sizeHint().height()+20 ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
status.setCaption(i18n("Writing Phone Data") );
status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
status.show();
status.raise();
qApp->processEvents();
int error=initDevice(&s);
qDebug("GSM Init %d (no error is %d)", error, ERR_NONE);
if ( error != ERR_NONE )
return false;
GSM_Phone_Functions *Phone;
GSM_CalendarEntry Note;
bool start = true;
Phone=s.Phone.Functions;
bool gshutdown = false;
QPtrList<Event> er = calendar->rawEvents();
Event* ev = er.first();
QString message = i18n("Processing event # ");
int procCount = 0;
while ( ev ) {
//qDebug("i %d ", ++i);
if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { // event was changed during sync or is a new one
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
event2GSM( ev, &Note );
if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete
error = Phone->DeleteCalendar(&s, &Note);
}
else if ( ev->getID(mProfileName).isEmpty() ) { // add new
// we have to do this later after deleting
}
else { // change existing
error = Phone->SetCalendar(&s, &Note);
}
}
ev = er.next();
}
ev = er.first();
// pending get empty slots
while ( ev ) {
if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && ev->tempSyncStat() != SYNC_TEMPSTATE_DELETE) {
if ( ev->getID(mProfileName).isEmpty() ) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
//int newID ;//= pending
//ev->setID(mProfileName, QString::number( newID ));
event2GSM( ev, &Note );
Note.Location = 0;
error = Phone->AddCalendar(&s, &Note);
ev->setID( mProfileName, QString::number( Note.Location ) );
qDebug("New Calendar. Location %d ",Note.Location );
afterSave( ev );
} else {
afterSave( ev ); // setting temp sync stat for changed items
}
}
ev = er.next();
}
GSM_ToDoEntry ToDoEntry;
QPtrList<Todo> tl = calendar->rawTodos();
Todo* to = tl.first();
message = i18n("Processing todo # ");
procCount = 0;
while ( to ) {
if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
todo2GSM( to, &ToDoEntry );
if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete
error=Phone->DeleteToDo(&s,&ToDoEntry);
}
else if ( to->getID("Sharp_DTM").isEmpty() ) { // add new
;
}
else { // change existing
error=Phone->SetToDo(&s,&ToDoEntry);
}
}
to = tl.next();
}
// pending get empty slots
to = tl.first();
while ( to ) {
if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && to->tempSyncStat() != SYNC_TEMPSTATE_DELETE) {
if ( to->getID(mProfileName).isEmpty() ) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
//int newID ;//= pending
//to->setID(mProfileName, QString::number( newID ));
todo2GSM( to, &ToDoEntry );
ToDoEntry.Location = 0;
error=Phone->AddToDo(&s,&ToDoEntry);
to->setID(mProfileName, QString::number( ToDoEntry.Location ));
afterSave( to );
qDebug("New Todo. Location %d ",ToDoEntry.Location );
} else {
afterSave( to );
}
}
to = tl.next();
}
return true;
}
QString PhoneFormat::dtToGSM( const QDateTime& dti, bool useTZ )
{
QString datestr;
QString timestr;
int offset = KGlobal::locale()->localTimeOffset( dti );
QDateTime dt;
if (useTZ)
dt = dti.addSecs ( -(offset*60));
else
dt = dti;
if(dt.date().isValid()){
const QDate& date = dt.date();
datestr.sprintf("%04d%02d%02d",
date.year(), date.month(), date.day());
}
if(dt.time().isValid()){
const QTime& time = dt.time();
timestr.sprintf("T%02d%02d%02d",
time.hour(), time.minute(), time.second());
}
return datestr + timestr;
}
QString PhoneFormat::getEventString( Event* event )
{
#if 0
QStringList list;
list.append( QString::number(event->zaurusId() ) );
list.append( event->categories().join(",") );
if ( !event->summary().isEmpty() )
list.append( event->summary() );
else
list.append("" );
if ( !event->location().isEmpty() )
list.append( event->location() );
else
list.append("" );
if ( !event->description().isEmpty() )
list.append( event->description() );
else
list.append( "" );
if ( event->doesFloat () ) {
list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false ));
list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6
list.append( "1" );
}
else {
list.append( dtToString( event->dtStart()) );
list.append( dtToString( event->dtEnd()) ); //6
list.append( "0" );
}
bool noAlarm = true;
if ( event->alarms().count() > 0 ) {
Alarm * al = event->alarms().first();
if ( al->enabled() ) {
noAlarm = false;
list.append( "0" ); // yes, 0 == alarm
list.append( QString::number( al->startOffset().asSeconds()/(-60) ) );
if ( al->type() == Alarm::Audio )
list.append( "1" ); // type audio
else
list.append( "0" ); // type silent
}
}
if ( noAlarm ) {
list.append( "1" ); // yes, 1 == no alarm
list.append( "0" ); // no alarm offset
list.append( "1" ); // type
}
// next is: 11
// next is: 11-16 are recurrence
Recurrence* rec = event->recurrence();
bool writeEndDate = false;
switch ( rec->doesRecur() )
{
case Recurrence::rDaily: // 0
list.append( "0" );
list.append( QString::number( rec->frequency() ));//12
list.append( "0" );
list.append( "0" );
writeEndDate = true;
break;
case Recurrence::rWeekly:// 1
list.append( "1" );
list.append( QString::number( rec->frequency()) );//12
list.append( "0" );
{
int days = 0;
QBitArray weekDays = rec->days();
int i;
for( i = 1; i <= 7; ++i ) {
if ( weekDays[i-1] ) {
days += 1 << (i-1);
}
}
list.append( QString::number( days ) );
}
//pending weekdays
writeEndDate = true;
break;
case Recurrence::rMonthlyPos:// 2
list.append( "2" );
list.append( QString::number( rec->frequency()) );//12
writeEndDate = true;
{
int count = 1;
QPtrList<Recurrence::rMonthPos> rmp;
rmp = rec->monthPositions();
if ( rmp.first()->negative )
count = 5 - rmp.first()->rPos - 1;
else
count = rmp.first()->rPos - 1;
list.append( QString::number( count ) );
}
list.append( "0" );
break;
case Recurrence::rMonthlyDay:// 3
list.append( "3" );
list.append( QString::number( rec->frequency()) );//12
diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h
index 7b7dd04..33b2091 100644
--- a/libkcal/phoneformat.h
+++ b/libkcal/phoneformat.h
@@ -1,65 +1,67 @@
/*
This file is part of libkcal.
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef PHONEFORMAT_H
#define PHONEFORMAT_H
#include <qstring.h>
#include "scheduler.h"
+#include "vcalformat.h"
#include "calformat.h"
extern "C" {
#include "../gammu/emb/common/gammu.h"
}
namespace KCal {
/**
This class implements the calendar format used by Phone.
*/
class Event;
class Todo;
class PhoneFormat : public QObject {
public:
/** Create new iCalendar format. */
PhoneFormat(QString profileName, QString device,QString connection, QString model);
virtual ~PhoneFormat();
bool load( Calendar * ,Calendar * );
bool save( Calendar * );
bool fromString( Calendar *, const QString & );
QString toString( Calendar * );
static ulong getCsum( const QStringList & );
static ulong getCsumTodo( Todo* to );
static ulong getCsumEvent( Event* ev );
private:
+ VCalFormat vfconverter;
void event2GSM( Event* ev, GSM_CalendarEntry*Note );
void todo2GSM( Todo* ev, GSM_ToDoEntry *ToDo );
int initDevice(GSM_StateMachine *s);
QString getEventString( Event* );
QString getTodoString( Todo* );
QString dtToGSM( const QDateTime& dt, bool useTZ = true );
QString mProfileName, mDevice, mConnection, mModel;
void afterSave( Incidence* );
};
}
#endif
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index 72a781a..1167e58 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -1,423 +1,442 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brwon
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <qapplication.h>
#include <qdatetime.h>
#include <qstring.h>
#include <qptrlist.h>
#include <qregexp.h>
#include <qclipboard.h>
#include <qdialog.h>
#include <qfile.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <klocale.h>
#include "vcc.h"
#include "vobject.h"
#include "vcaldrag.h"
#include "calendar.h"
#include "vcalformat.h"
using namespace KCal;
VCalFormat::VCalFormat()
{
}
VCalFormat::~VCalFormat()
{
}
bool VCalFormat::load(Calendar *calendar, const QString &fileName)
{
mCalendar = calendar;
clearException();
kdDebug(5800) << "VCalFormat::load() " << fileName << endl;
VObject *vcal = 0;
// this is not necessarily only 1 vcal. Could be many vcals, or include
// a vcard...
vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
if (!vcal) {
setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
return FALSE;
}
// any other top-level calendar stuff should be added/initialized here
// put all vobjects into their proper places
populate(vcal);
// clean up from vcal API stuff
cleanVObjects(vcal);
cleanStrTbl();
return true;
}
bool VCalFormat::save(Calendar *calendar, const QString &fileName)
{
mCalendar = calendar;
QString tmpStr;
VObject *vcal, *vo;
kdDebug(5800) << "VCalFormat::save(): " << fileName << endl;
vcal = newVObject(VCCalProp);
// addPropValue(vcal,VCLocationProp, "0.0");
addPropValue(vcal,VCProdIdProp, productId());
tmpStr = mCalendar->getTimeZoneStr();
//qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
// TODO STUFF
QPtrList<Todo> todoList = mCalendar->rawTodos();
QPtrListIterator<Todo> qlt(todoList);
for (; qlt.current(); ++qlt) {
vo = eventToVTodo(qlt.current());
addVObjectProp(vcal, vo);
}
// EVENT STUFF
QPtrList<Event> events = mCalendar->rawEvents();
Event *ev;
for(ev=events.first();ev;ev=events.next()) {
vo = eventToVEvent(ev);
addVObjectProp(vcal, vo);
}
writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
cleanVObjects(vcal);
cleanStrTbl();
if (QFile::exists(fileName)) {
kdDebug(5800) << "No error" << endl;
return true;
} else {
kdDebug(5800) << "Error" << endl;
return false; // error
}
}
bool VCalFormat::fromString( Calendar *calendar, const QString &text )
{
// TODO: Factor out VCalFormat::fromString()
QCString data = text.utf8();
if ( !data.size() ) return false;
VObject *vcal = Parse_MIME( data.data(), data.size());
if ( !vcal ) return false;
VObjectIterator i;
VObject *curvo;
initPropIterator( &i, vcal );
// we only take the first object. TODO: parse all incidences.
do {
curvo = nextVObject( &i );
} while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
strcmp( vObjectName( curvo ), VCTodoProp ) );
if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
Event *event = VEventToEvent( curvo );
calendar->addEvent( event );
} else {
kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl;
deleteVObject( vcal );
return false;
}
deleteVObject( vcal );
return true;
}
+QString VCalFormat::eventToString( Event * event)
+{
+ if ( !event ) return QString::null;
+ VObject *vevent = eventToVEvent( event );
+ char *buf = writeMemVObject( 0, 0, vevent );
+ QString result( buf );
+ cleanVObject( vevent );
+ return result;
+}
+QString VCalFormat::todoToString( Todo * todo )
+{
+ if ( !todo ) return QString::null;
+ VObject *vevent = eventToVTodo( todo );
+ char *buf = writeMemVObject( 0, 0, vevent );
+ QString result( buf );
+ cleanVObject( vevent );
+ return result;
+}
+
QString VCalFormat::toString( Calendar *calendar )
{
// TODO: Factor out VCalFormat::asString()
VObject *vcal = newVObject(VCCalProp);
addPropValue( vcal, VCProdIdProp, CalFormat::productId() );
QString tmpStr = mCalendar->getTimeZoneStr();
addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() );
addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
// TODO: Use all data.
QPtrList<Event> events = calendar->events();
Event *event = events.first();
if ( !event ) return QString::null;
VObject *vevent = eventToVEvent( event );
addVObjectProp( vcal, vevent );
char *buf = writeMemVObject( 0, 0, vcal );
QString result( buf );
cleanVObject( vcal );
return result;
}
VObject *VCalFormat::eventToVTodo(const Todo *anEvent)
{
VObject *vtodo;
QString tmpStr;
QStringList tmpStrList;
vtodo = newVObject(VCTodoProp);
// due date
if (anEvent->hasDueDate()) {
tmpStr = qDateTimeToISO(anEvent->dtDue(),
!anEvent->doesFloat());
addPropValue(vtodo, VCDueProp, tmpStr.local8Bit());
}
// start date
if (anEvent->hasStartDate()) {
tmpStr = qDateTimeToISO(anEvent->dtStart(),
!anEvent->doesFloat());
addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit());
}
// creation date
tmpStr = qDateTimeToISO(anEvent->created());
addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit());
// unique id
addPropValue(vtodo, VCUniqueStringProp,
anEvent->uid().local8Bit());
// revision
tmpStr.sprintf("%i", anEvent->revision());
addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit());
// last modification date
tmpStr = qDateTimeToISO(anEvent->lastModified());
addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit());
// organizer stuff
tmpStr = "MAILTO:" + anEvent->organizer();
addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit());
// attendees
if (anEvent->attendeeCount() != 0) {
QPtrList<Attendee> al = anEvent->attendees();
QPtrListIterator<Attendee> ai(al);
Attendee *curAttendee;
for (; ai.current(); ++ai) {
curAttendee = ai.current();
if (!curAttendee->email().isEmpty() &&
!curAttendee->name().isEmpty())
tmpStr = "MAILTO:" + curAttendee->name() + " <" +
curAttendee->email() + ">";
else if (curAttendee->name().isEmpty())
tmpStr = "MAILTO: " + curAttendee->email();
else if (curAttendee->email().isEmpty())
tmpStr = "MAILTO: " + curAttendee->name();
else if (curAttendee->name().isEmpty() &&
curAttendee->email().isEmpty())
kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit());
addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
}
}
// description BL:
if (!anEvent->description().isEmpty()) {
VObject *d = addPropValue(vtodo, VCDescriptionProp,
anEvent->description().local8Bit());
if (anEvent->description().find('\n') != -1)
addProp(d, VCQuotedPrintableProp);
}
// summary
if (!anEvent->summary().isEmpty())
addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit());
if (!anEvent->location().isEmpty())
addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit());
// completed
// status
// backward compatibility, KOrganizer used to interpret only these two values
addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" :
"NEEDS_ACTION");
// completion date
if (anEvent->hasCompletedDate()) {
tmpStr = qDateTimeToISO(anEvent->completed());
addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit());
}
// priority
tmpStr.sprintf("%i",anEvent->priority());
addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit());
// related event
if (anEvent->relatedTo()) {
addPropValue(vtodo, VCRelatedToProp,
anEvent->relatedTo()->uid().local8Bit());
}
// categories
tmpStrList = anEvent->categories();
tmpStr = "";
QString catStr;
for ( QStringList::Iterator it = tmpStrList.begin();
it != tmpStrList.end();
++it ) {
catStr = *it;
if (catStr[0] == ' ')
tmpStr += catStr.mid(1);
else
tmpStr += catStr;
// this must be a ';' character as the vCalendar specification requires!
// vcc.y has been hacked to translate the ';' to a ',' when the vcal is
// read in.
tmpStr += ";";
}
if (!tmpStr.isEmpty()) {
tmpStr.truncate(tmpStr.length()-1);
addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit());
}
// alarm stuff
kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl;
QPtrList<Alarm> alarms = anEvent->alarms();
Alarm* alarm;
for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
if (alarm->enabled()) {
VObject *a = addProp(vtodo, VCDAlarmProp);
tmpStr = qDateTimeToISO(alarm->time());
addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
addPropValue(a, VCRepeatCountProp, "1");
addPropValue(a, VCDisplayStringProp, "beep!");
if (alarm->type() == Alarm::Audio) {
a = addProp(vtodo, VCAAlarmProp);
addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
addPropValue(a, VCRepeatCountProp, "1");
addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
}
else if (alarm->type() == Alarm::Procedure) {
a = addProp(vtodo, VCPAlarmProp);
addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
addPropValue(a, VCRepeatCountProp, "1");
addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
}
}
}
if (anEvent->pilotId()) {
// pilot sync stuff
tmpStr.sprintf("%i",anEvent->pilotId());
addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit());
tmpStr.sprintf("%i",anEvent->syncStatus());
addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit());
}
return vtodo;
}
VObject* VCalFormat::eventToVEvent(const Event *anEvent)
{
VObject *vevent;
QString tmpStr;
QStringList tmpStrList;
vevent = newVObject(VCEventProp);
// start and end time
tmpStr = qDateTimeToISO(anEvent->dtStart(),
!anEvent->doesFloat());
addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit());
// events that have time associated but take up no time should
// not have both DTSTART and DTEND.
if (anEvent->dtStart() != anEvent->dtEnd()) {
tmpStr = qDateTimeToISO(anEvent->dtEnd(),
!anEvent->doesFloat());
addPropValue(vevent, VCDTendProp, tmpStr.local8Bit());
}
// creation date
tmpStr = qDateTimeToISO(anEvent->created());
addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit());
// unique id
addPropValue(vevent, VCUniqueStringProp,
anEvent->uid().local8Bit());
// revision
tmpStr.sprintf("%i", anEvent->revision());
addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit());
// last modification date
tmpStr = qDateTimeToISO(anEvent->lastModified());
addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit());
// attendee and organizer stuff
tmpStr = "MAILTO:" + anEvent->organizer();
addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit());
if (anEvent->attendeeCount() != 0) {
QPtrList<Attendee> al = anEvent->attendees();
QPtrListIterator<Attendee> ai(al);
Attendee *curAttendee;
// TODO: Put this functionality into Attendee class
for (; ai.current(); ++ai) {
curAttendee = ai.current();
if (!curAttendee->email().isEmpty() &&
!curAttendee->name().isEmpty())
tmpStr = "MAILTO:" + curAttendee->name() + " <" +
curAttendee->email() + ">";
else if (curAttendee->name().isEmpty())
tmpStr = "MAILTO: " + curAttendee->email();
else if (curAttendee->email().isEmpty())
tmpStr = "MAILTO: " + curAttendee->name();
else if (curAttendee->name().isEmpty() &&
curAttendee->email().isEmpty())
kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit());
addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");;
addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
}
}
diff --git a/libkcal/vcalformat.h b/libkcal/vcalformat.h
index d4cecbc..8490125 100644
--- a/libkcal/vcalformat.h
+++ b/libkcal/vcalformat.h
@@ -1,108 +1,110 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brown
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef _VCALFORMAT_H
#define _VCALFORMAT_H
#include "calformat.h"
#define _VCAL_VERSION "1.0"
class VObject;
namespace KCal {
/**
This class implements the vCalendar format. It provides methods for
loading/saving/converting vCalendar format data into the internal KOrganizer
representation as Calendar and Events.
@short vCalendar format implementation
*/
class VCalFormat : public CalFormat {
public:
VCalFormat();
virtual ~VCalFormat();
/** loads a calendar on disk in vCalendar format into the current calendar.
* any information already present is lost. Returns TRUE if successful,
* else returns FALSE.
* @param fileName the name of the calendar on disk.
*/
bool load(Calendar *,const QString &fileName);
/** writes out the calendar to disk in vCalendar format. Returns true if
* successful and false on error.
* @param fileName the name of the file
*/
bool save(Calendar *,const QString &fileName);
/**
Parse string and populate calendar with that information.
*/
bool fromString( Calendar *, const QString & );
/**
Return calendar information as string.
*/
QString toString( Calendar * );
+ QString eventToString( Event * );
+ QString todoToString( Todo * );
protected:
/** translates a VObject of the TODO type into a Event */
Todo *VTodoToEvent(VObject *vtodo);
/** translates a VObject into a Event and returns a pointer to it. */
Event *VEventToEvent(VObject *vevent);
/** translate a Event into a VTodo-type VObject and return pointer */
VObject *eventToVTodo(const Todo *anEvent);
/** translate a Event into a VObject and returns a pointer to it. */
VObject* eventToVEvent(const Event *anEvent);
/** takes a QDate and returns a string in the format YYYYMMDDTHHMMSS */
QString qDateToISO(const QDate &);
/** takes a QDateTime and returns a string in format YYYYMMDDTHHMMSS */
QString qDateTimeToISO(const QDateTime &, bool zulu=TRUE);
/** takes a string in the format YYYYMMDDTHHMMSS and returns a
* valid QDateTime. */
QDateTime ISOToQDateTime(const QString & dtStr);
/** takes a string in the format YYYYMMDD and returns a
* valid QDate. */
QDate ISOToQDate(const QString & dtStr);
/** takes a vCalendar tree of VObjects, and puts all of them that have
* the "event" property into the dictionary, todos in the todo-list, etc. */
void populate(VObject *vcal);
/** takes a number 0 - 6 and returns the two letter string of that day,
* i.e. MO, TU, WE, etc. */
const char *dayFromNum(int day);
/** the reverse of the above function. */
int numFromDay(const QString &day);
Attendee::PartStat readStatus(const char *s) const;
QCString writeStatus(Attendee::PartStat status) const;
private:
Calendar *mCalendar;
QPtrList<Event> mEventsRelate; // events with relations
QPtrList<Todo> mTodosRelate; // todos with relations
};
}
#endif