summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--korganizer/calendarview.cpp2
-rw-r--r--libkcal/calendar.h1
-rw-r--r--libkcal/calendarlocal.cpp25
-rw-r--r--libkcal/calendarlocal.h1
-rw-r--r--libkdepim/ksyncmanager.cpp5
5 files changed, 29 insertions, 5 deletions
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp
index 307027a..e45240a 100644
--- a/korganizer/calendarview.cpp
+++ b/korganizer/calendarview.cpp
@@ -1147,1025 +1147,1025 @@ void CalendarView::startAlarm( QString mess , QString filename)
topLevelWidget()->showNormal();
topLevelWidget()->setActiveWindow();
topLevelWidget()->raise();
mAlarmDialog->eventNotification( mess, KOPrefs::instance()->mAlarmPlayBeeps, filename, true,KOPrefs::instance()->mAlarmBeepInterval ,KOPrefs::instance()->mAlarmSuspendCount );
QTimer::singleShot( 2000, this, SLOT( checkNextTimerAlarm() ) );
}
void CalendarView::checkNextTimerAlarm()
{
mCalendar->checkAlarmForIncidence( 0, true );
}
void CalendarView::computeAlarm( QString msg )
{
QString mess = msg;
QString mAlarmMessage = mess.mid( 9 );
QString filename = MainWindow::resourcePath();
filename += "koalarm.wav";
QString tempfilename;
if ( mess.left( 13 ) == "suspend_alarm") {
bool error = false;
int len = mess.mid( 13 ).find("+++");
if ( len < 2 )
error = true;
else {
tempfilename = mess.mid( 13, len );
if ( !QFile::exists( tempfilename ) )
error = true;
}
if ( ! error ) {
filename = tempfilename;
}
mAlarmMessage = mess.mid( 13+len+3 );
//qDebug("suspend file %s ",tempfilename.latin1() );
startAlarm( mAlarmMessage, filename);
return;
}
if ( mess.left( 11 ) == "timer_alarm") {
//mTimerTime = 0;
startAlarm( mess.mid( 11 ), filename );
return;
}
if ( mess.left( 10 ) == "proc_alarm") {
bool error = false;
int len = mess.mid( 10 ).find("+++");
if ( len < 2 )
error = true;
else {
tempfilename = mess.mid( 10, len );
if ( !QFile::exists( tempfilename ) )
error = true;
}
if ( error ) {
mAlarmMessage = "Procedure Alarm\nError - File not found\n";
mAlarmMessage += mess.mid( 10+len+3+9 );
} else {
//QCopEnvelope e("QPE/Application/kopi", "-writeFileSilent");
//qDebug("-----system command %s ",tempfilename.latin1() );
#ifndef _WIN32_
if ( vfork () == 0 ) {
execl ( tempfilename.latin1(), 0 );
return;
}
#else
QProcess* p = new QProcess();
p->addArgument( tempfilename.latin1() );
p->start();
return;
#endif
return;
}
//qDebug("+++++++system command %s ",tempfilename.latin1() );
}
if ( mess.left( 11 ) == "audio_alarm") {
bool error = false;
int len = mess.mid( 11 ).find("+++");
if ( len < 2 )
error = true;
else {
tempfilename = mess.mid( 11, len );
if ( !QFile::exists( tempfilename ) )
error = true;
}
if ( ! error ) {
filename = tempfilename;
}
mAlarmMessage = mess.mid( 11+len+3+9 );
//qDebug("audio file command %s ",tempfilename.latin1() );
}
if ( mess.left( 9 ) == "cal_alarm") {
mAlarmMessage = mess.mid( 9 ) ;
}
startAlarm( mAlarmMessage, filename );
}
void CalendarView::addSuspendAlarm(const QDateTime &qdt, const QString &noti )
{
//qDebug("+++++addSUSPENDAlarm %s %s ", qdt.toString().latin1() , noti.latin1() );
mSuspendAlarmNotification = noti;
int ms = QDateTime::currentDateTime().secsTo( qdt )*1000;
//qDebug("Suspend Alarm timer started with secs: %d ", ms/1000);
mSuspendTimer->start( ms , true );
#ifdef DESKTOP_VERSION
if ( QApplication::desktop()->width() < 1024 ) {
QString mess = qdt.toString( "yyyy-MM-dd hh:mm:ss" ) + "\n" + noti;
//qDebug("nextsuspendalarm = \n%s ",mess.latin1() );
QString fn = QDir::homeDirPath() + "/.kopi_suspend_alarm";
QFile file( fn );
if (!file.open( IO_WriteOnly ) ) {
qDebug("KO: Error writing next suspend alarm file %s\nContent: \n%s ", fn.latin1(), mess.latin1());
} else {
QTextStream ts( &file );
ts << mess;
file.close();
}
}
#endif
}
void CalendarView::addAlarm(const QDateTime &qdt, const QString &noti )
{
mNextAlarmDateTime = qdt;
//qDebug("+++++addAlarm %s %s ", qdt.toString().latin1() , noti.latin1() );
if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) {
#ifndef DESKTOP_VERSION
AlarmServer::addAlarm ( qdt,"koalarm", noti.utf8() );
#endif
return;
}
#ifdef DESKTOP_VERSION
if ( QApplication::desktop()->width() < 1024 ) {
QString mess = qdt.toString( "yyyy-MM-dd hh:mm:ss" ) + "\n" + noti;
//qDebug("nextalarm = \n%s ",mess.latin1() );
QString fn = QDir::homeDirPath() + "/.kopi_next_alarm";
QFile file( fn );
if (!file.open( IO_WriteOnly ) ) {
qDebug("KO: Error writing next alarm file %s\nContent: \n%s ", fn.latin1(), mess.latin1());
} else {
QTextStream ts( &file );
ts << mess;
file.close();
}
}
#endif
int maxSec;
//maxSec = 5; //testing only
maxSec = 86400+3600; // one day+1hour
mAlarmNotification = noti;
int sec = QDateTime::currentDateTime().secsTo( qdt );
if ( sec > maxSec ) {
mRecheckAlarmTimer->start( maxSec * 1000 );
// qDebug("recheck Alarm timer started with secs: %d next alarm in sec:%d", maxSec,sec );
return;
} else {
mRecheckAlarmTimer->stop();
}
//qDebug("Alarm timer started with secs: %d ", sec);
mAlarmTimer->start( sec * 1000 , true );
}
// called by mRecheckAlarmTimer to get next alarm
// we need this, because a QTimer has only a max range of 25 days
void CalendarView::recheckTimerAlarm()
{
mAlarmTimer->stop();
mRecheckAlarmTimer->stop();
mCalendar->checkAlarmForIncidence( 0, true );
}
#ifndef DESKTOP_VERSION
void CalendarView::removeAlarm(const QDateTime &qdt, const QString &noti )
#else
void CalendarView::removeAlarm(const QDateTime &, const QString & )
#endif
{
//qDebug("-----removeAlarm %s %s ", qdt.toString().latin1() , noti.latin1() );
if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) {
#ifndef DESKTOP_VERSION
AlarmServer::deleteAlarm (qdt ,"koalarm" ,noti.utf8() );
#endif
return;
}
mAlarmTimer->stop();
}
void CalendarView::selectWeekNum ( int num )
{
dateNavigator()->blockSignals( true );
dateNavigator()->selectWeek( num );
dateNavigator()->blockSignals( false );
mViewManager->showWeekView();
}
KOViewManager *CalendarView::viewManager()
{
return mViewManager;
}
KODialogManager *CalendarView::dialogManager()
{
return mDialogManager;
}
QDate CalendarView::startDate()
{
DateList dates = mNavigator->selectedDates();
return dates.first();
}
QDate CalendarView::endDate()
{
DateList dates = mNavigator->selectedDates();
return dates.last();
}
void CalendarView::createPrinter()
{
#ifndef KORG_NOPRINTER
if (!mCalPrinter) {
mCalPrinter = new CalPrinter(this, mCalendar);
connect(this, SIGNAL(configChanged()), mCalPrinter, SLOT(updateConfig()));
}
#endif
}
//KOPrefs::instance()->mWriteBackFile
//KOPrefs::instance()->mWriteBackExistingOnly
// 0 syncPrefsGroup->addRadio(i18n("Take local entry on conflict"));
// 1 syncPrefsGroup->addRadio(i18n("Take remote entry on conflict"));
// 2 syncPrefsGroup->addRadio(i18n("Take newest entry on conflict"));
// 3 syncPrefsGroup->addRadio(i18n("Ask for every entry on conflict"));
// 4 syncPrefsGroup->addRadio(i18n("Force take local entry always"));
// 5 syncPrefsGroup->addRadio(i18n("Force take remote entry always"));
int CalendarView::takeEvent( Incidence* local, Incidence* remote, int mode , bool full )
{
// 0 equal
// 1 take local
// 2 take remote
// 3 cancel
QDateTime lastSync = mLastCalendarSync;
QDateTime localMod = local->lastModified();
QDateTime remoteMod = remote->lastModified();
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) {
bool remCh, locCh;
remCh = ( remote->getCsum(mCurrentSyncDevice) != local->getCsum(mCurrentSyncDevice) );
//if ( remCh )
//qDebug("loc %s rem %s", local->getCsum(mCurrentSyncDevice).latin1(), remote->getCsum(mCurrentSyncDevice).latin1() );
locCh = ( localMod > mLastCalendarSync );
if ( !remCh && ! locCh ) {
//qDebug("both not changed ");
lastSync = localMod.addDays(1);
if ( mode <= SYNC_PREF_ASK )
return 0;
} else {
if ( locCh ) {
//qDebug("loc changed %d %s %s", local->revision() , localMod.toString().latin1(), mLastCalendarSync.toString().latin1());
lastSync = localMod.addDays( -1 );
if ( !remCh )
remoteMod = ( lastSync.addDays( -1 ) );
} else {
//qDebug(" not loc changed ");
lastSync = localMod.addDays( 1 );
if ( remCh )
remoteMod =( lastSync.addDays( 1 ) );
}
}
full = true;
if ( mode < SYNC_PREF_ASK )
mode = SYNC_PREF_ASK;
} else {
if ( localMod == remoteMod )
// if ( local->revision() == remote->revision() )
return 0;
}
// qDebug(" %d %d conflict on %s %s ", mode, full, local->summary().latin1(), remote->summary().latin1() );
//qDebug("%s %d %s %d", localMod.toString().latin1() , local->revision(), remoteMod.toString().latin1(), remote->revision());
//qDebug("%d %d %d %d ", localMod.time().second(), localMod.time().msec(), remoteMod.time().second(), remoteMod.time().msec() );
//full = true; //debug only
if ( full ) {
bool equ = false;
if ( local->typeID() == eventID ) {
equ = (*((Event*) local) == *((Event*) remote));
}
else if ( local->typeID() == todoID )
equ = (*((Todo*) local) == (*(Todo*) remote));
else if ( local->typeID() == journalID )
equ = (*((Journal*) local) == *((Journal*) remote));
if ( equ ) {
//qDebug("equal ");
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) {
local->setCsum( mCurrentSyncDevice, remote->getCsum(mCurrentSyncDevice) );
}
if ( mode < SYNC_PREF_FORCE_LOCAL )
return 0;
}//else //debug only
//qDebug("not equal %s %s ", local->summary().latin1(), remote->summary().latin1());
}
int result;
bool localIsNew;
//qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , localMod.toString().latin1() , remoteMod.toString().latin1() );
// ************************************************
// ************************************************
// ************************************************
// We may have that lastSync > remoteMod AND lastSync > localMod
// BUT remoteMod != localMod
if ( full && mode < SYNC_PREF_NEWEST )
mode = SYNC_PREF_ASK;
switch( mode ) {
case SYNC_PREF_LOCAL:
if ( lastSync > remoteMod )
return 1;
if ( lastSync > localMod )
return 2;
return 1;
break;
case SYNC_PREF_REMOTE:
if ( lastSync > localMod )
return 2;
if ( lastSync > remoteMod )
return 1;
return 2;
break;
case SYNC_PREF_NEWEST:
if ( localMod >= remoteMod )
return 1;
else
return 2;
break;
case SYNC_PREF_ASK:
qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() );
if ( lastSync > remoteMod && lastSync > localMod)
return 0;
if ( lastSync > remoteMod )
return 1;
if ( lastSync > localMod )
return 2;
qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() );
localIsNew = localMod >= remoteMod;
if ( localIsNew )
getEventViewerDialog()->setColorMode( 1 );
else
getEventViewerDialog()->setColorMode( 2 );
getEventViewerDialog()->setIncidence(local);
if ( localIsNew )
getEventViewerDialog()->setColorMode( 2 );
else
getEventViewerDialog()->setColorMode( 1 );
getEventViewerDialog()->addIncidence(remote);
getEventViewerDialog()->setColorMode( 0 );
//qDebug("local %d remote %d ",local->relatedTo(),remote->relatedTo() );
getEventViewerDialog()->setCaption( mCurrentSyncDevice +i18n(" : Conflict! Please choose entry!"));
getEventViewerDialog()->showMe();
result = getEventViewerDialog()->executeS( localIsNew );
return result;
break;
case SYNC_PREF_FORCE_LOCAL:
return 1;
break;
case SYNC_PREF_FORCE_REMOTE:
return 2;
break;
default:
// SYNC_PREF_TAKE_BOTH not implemented
break;
}
return 0;
}
Event* CalendarView::getLastSyncEvent()
{
Event* lse;
//qDebug("CurrentSyncDevice %s ",mCurrentSyncDevice .latin1() );
lse = mCalendar->event( "last-syncEvent-"+mCurrentSyncDevice );
if (!lse) {
lse = new Event();
lse->setUid( "last-syncEvent-"+mCurrentSyncDevice );
QString sum = "";
if ( mSyncManager->mExternSyncProfiles.contains( mCurrentSyncDevice ) )
sum = "E: ";
lse->setSummary(sum+mCurrentSyncDevice + i18n(" - sync event"));
lse->setDtStart( mLastCalendarSync );
lse->setDtEnd( mLastCalendarSync.addSecs( 7200 ) );
lse->setCategories( i18n("SyncEvent") );
lse->setReadOnly( true );
lse->setCalID( 1 );
mCalendar->addEvent( lse );
}
return lse;
}
// we check, if the to delete event has a id for a profile
// if yes, we set this id in the profile to delete
void CalendarView::checkExternSyncEvent( QPtrList<Event> lastSync , Incidence* toDelete )
{
if ( lastSync.count() == 0 ) {
//qDebug(" lastSync.count() == 0");
return;
}
if ( toDelete->typeID() == journalID )
return;
Event* eve = lastSync.first();
while ( eve ) {
QString id = toDelete->getID( eve->uid().mid( 15 ) ); // this is the sync profile name
if ( !id.isEmpty() ) {
QString des = eve->description();
QString pref = "e";
if ( toDelete->typeID() == todoID )
pref = "t";
des += pref+ id + ",";
eve->setReadOnly( false );
eve->setDescription( des );
//qDebug("setdes %s ", des.latin1());
eve->setReadOnly( true );
}
eve = lastSync.next();
}
}
void CalendarView::checkExternalId( Incidence * inc )
{
QPtrList<Event> lastSync = mCalendar->getExternLastSyncEvents() ;
checkExternSyncEvent( lastSync, inc );
}
bool CalendarView::synchronizeCalendar( Calendar* local, Calendar* remote, int mode )
{
bool syncOK = true;
int addedEvent = 0;
int addedEventR = 0;
int deletedEventR = 0;
int deletedEventL = 0;
int changedLocal = 0;
int changedRemote = 0;
int filteredIN = 0;
int filteredOUT = 0;
//QPtrList<Event> el = local->rawEvents();
Event* eventR;
QString uid;
int take;
Event* eventRSync;
Event* eventLSync;
clearAllViews();
QPtrList<Event> eventRSyncSharp = remote->getExternLastSyncEvents();
QPtrList<Event> eventLSyncSharp = local->getExternLastSyncEvents();
bool fullDateRange = false;
local->resetTempSyncStat();
mLastCalendarSync = QDateTime::currentDateTime();
if ( mSyncManager->syncWithDesktop() ) {
remote->resetPilotStat(1);
if ( KSyncManager::mRequestedSyncEvent.isValid() ) {
mLastCalendarSync = KSyncManager::mRequestedSyncEvent;
qDebug("KO: using extern time for calendar sync: %s ", mLastCalendarSync.toString().latin1() );
} else {
qDebug("KSyncManager::mRequestedSyncEvent has invalid datatime ");
}
}
QDateTime modifiedCalendar = mLastCalendarSync;
eventLSync = getLastSyncEvent();
eventR = remote->event("last-syncEvent-"+mCurrentSyncName );
if ( eventR ) {
qDebug("last-syncEvent on remote found ");
eventRSync = (Event*) eventR->clone();
remote->deleteEvent(eventR );
} else {
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL || mSyncManager->syncWithDesktop()) {
eventRSync = (Event*)eventLSync->clone();
} else {
fullDateRange = true;
eventRSync = new Event();
eventRSync->setSummary(mCurrentSyncName + i18n(" - sync event"));
eventRSync->setUid("last-syncEvent-"+mCurrentSyncName );
eventRSync->setDtStart( mLastCalendarSync );
eventRSync->setDtEnd( mLastCalendarSync.addSecs( 7200 ) );
eventRSync->setCategories( i18n("SyncEvent") );
}
}
if ( eventLSync->dtStart() == mLastCalendarSync )
fullDateRange = true;
if ( ! fullDateRange ) {
if ( eventLSync->dtStart() != eventRSync->dtStart() ) {
- qDebug("set fulldate to true %s %s" ,eventLSync->dtStart().toString().latin1(), eventRSync->dtStart().toString().latin1() );
+ qDebug("KO: Sync: Set fulldate to true! Local: %s --- Remote: %s" ,eventLSync->dtStart().toString().latin1(), eventRSync->dtStart().toString().latin1() );
//qDebug("%d %d %d %d ", eventLSync->dtStart().time().second(), eventLSync->dtStart().time().msec() , eventRSync->dtStart().time().second(), eventRSync->dtStart().time().msec());
fullDateRange = true;
}
}
if ( mSyncManager->syncWithDesktop() ) {
fullDateRange = ( eventLSync->dtStart() <= mLastCalendarSync && eventLSync->dtStart().addSecs(1) >= mLastCalendarSync );
}
if ( fullDateRange )
mLastCalendarSync = QDateTime::currentDateTime().addDays( -100*365);
else
mLastCalendarSync = eventLSync->dtStart();
// for resyncing if own file has changed
if ( mCurrentSyncDevice == "deleteaftersync" ) {
mLastCalendarSync = loadedFileVersion;
//qDebug("setting mLastCalendarSync ");
}
//qDebug("*************************** ");
qDebug("KO: mLastCalendarSync %s .Full: %d",mLastCalendarSync.toString().latin1(), fullDateRange);
QPtrList<Incidence> er = remote->rawIncidences();
Incidence* inR = er.first();
Incidence* inL;
QProgressBar bar( er.count(),0 );
bar.setCaption (i18n("Syncing - close to abort!") );
// ************** setting up filter *************
CalFilter *filterIN = 0;
CalFilter *filterOUT = 0;
CalFilter *filter = mFilters.first();
while(filter) {
if ( filter->name() == mSyncManager->mFilterInCal )
filterIN = filter;
if ( filter->name() == mSyncManager->mFilterOutCal )
filterOUT = filter;
filter = mFilters.next();
}
int w = 300;
if ( QApplication::desktop()->width() < 320 )
w = 220;
int h = bar.sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
bar.show();
int modulo = (er.count()/10)+1;
int incCounter = 0;
while ( inR ) {
if ( ! bar.isVisible() )
return false;
if ( incCounter % modulo == 0 )
bar.setProgress( incCounter );
++incCounter;
uid = inR->uid();
bool skipIncidence = false;
if ( uid.left(15) == QString("last-syncEvent-") )
skipIncidence = true;
QString idS;
qApp->processEvents();
if ( !skipIncidence ) {
inL = local->incidenceForUid( uid , false );
if ( inL ) { // maybe conflict - same uid in both calendars
if ( (take = takeEvent( inL, inR, mode, fullDateRange )) > 0 ) {
//qDebug("take %d %s ", take, inL->summary().latin1());
if ( take == 3 )
return false;
if ( take == 1 ) {// take local **********************
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL )
inL->setCsum( mCurrentSyncDevice, inR->getCsum(mCurrentSyncDevice) );
else
idS = inR->IDStr();
int calID = inR->calID();
remote->deleteIncidence( inR );
inR = inL->clone();
inR->setCalID( calID );
inR->setTempSyncStat( SYNC_TEMPSTATE_INITIAL );
if ( mGlobalSyncMode != SYNC_MODE_EXTERNAL )
inR->setIDStr( idS );
remote->addIncidence( inR );
if ( mSyncManager->syncWithDesktop() )
inR->setPilotId( 2 );
++changedRemote;
} else {// take remote **********************
if ( !inL->isReadOnly() ) {
idS = inL->IDStr();
int pid = inL->pilotId();
int calID = inL->calID();
local->deleteIncidence( inL );
inL = inR->clone();
inL->setCalID( calID );
if ( mSyncManager->syncWithDesktop() )
inL->setPilotId( pid );
inL->setIDStr( idS );
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) {
inL->setCsum( mCurrentSyncDevice, inR->getCsum(mCurrentSyncDevice) );
inL->setID( mCurrentSyncDevice, inR->getID(mCurrentSyncDevice) );
}
local->addIncidence( inL );
++changedLocal;
}
}
}
} else { // no conflict ********** add or delete remote
if ( !filterIN || filterIN->filterCalendarItem( inR ) ){
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) {
QString des = eventLSync->description();
QString pref = "e";
if ( inR->typeID() == todoID )
pref = "t";
if ( des.find(pref+ inR->getID(mCurrentSyncDevice) +"," ) >= 0 && mode != 5) { // delete it
inR->setTempSyncStat( SYNC_TEMPSTATE_DELETE );
//remote->deleteIncidence( inR );
++deletedEventR;
} else {
inR->setLastModified( modifiedCalendar );
inL = inR->clone();
inL->setIDStr( ":" );
inL->setCsum( mCurrentSyncDevice, inR->getCsum(mCurrentSyncDevice) );
inL->setID( mCurrentSyncDevice, inR->getID(mCurrentSyncDevice) );
inL->setCalID( 0 );// add to default cal
local->addIncidence( inL );
++addedEvent;
}
} else {
if ( inR->lastModified() > mLastCalendarSync || mode == 5 ) {
inR->setLastModified( modifiedCalendar );
inL = inR->clone();
inL->setIDStr( ":" );
inL->setCalID( 0 );// add to default cal
local->addIncidence( inL );
++addedEvent;
} else {
checkExternSyncEvent(eventRSyncSharp, inR);
remote->deleteIncidence( inR );
++deletedEventR;
}
}
} else {
++filteredIN;
}
}
}
inR = er.next();
}
QPtrList<Incidence> el = local->rawIncidences();
inL = el.first();
modulo = (el.count()/10)+1;
bar.setCaption (i18n("Add / remove events") );
bar.setTotalSteps ( el.count() ) ;
bar.show();
incCounter = 0;
while ( inL ) {
qApp->processEvents();
if ( ! bar.isVisible() )
return false;
if ( incCounter % modulo == 0 )
bar.setProgress( incCounter );
++incCounter;
uid = inL->uid();
bool skipIncidence = false;
if ( uid.left(15) == QString("last-syncEvent-") )
skipIncidence = true;
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL && inL->typeID() == journalID )
skipIncidence = true;
if ( !skipIncidence ) {
inR = remote->incidenceForUid( uid , true );
if ( ! inR ) {
if ( !filterOUT || filterOUT->filterCalendarItem( inL ) ){
// no conflict ********** add or delete local
if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) {
if ( !inL->getID(mCurrentSyncDevice).isEmpty() && mode != 4 ) {
checkExternSyncEvent(eventLSyncSharp, inL);
local->deleteIncidence( inL );
++deletedEventL;
} else {
if ( ! mSyncManager->mWriteBackExistingOnly ) {
inL->removeID(mCurrentSyncDevice );
++addedEventR;
//qDebug("remote added Incidence %s ", inL->summary().latin1());
inL->setLastModified( modifiedCalendar );
inR = inL->clone();
inR->setIDStr( ":" );
inR->setTempSyncStat( SYNC_TEMPSTATE_INITIAL );
inR->setCalID( 0 );// add to default cal
remote->addIncidence( inR );
}
}
} else {
if ( inL->lastModified() < mLastCalendarSync && mode != 4 ) {
checkExternSyncEvent(eventLSyncSharp, inL);
local->deleteIncidence( inL );
++deletedEventL;
} else {
if ( ! mSyncManager->mWriteBackExistingOnly ) {
++addedEventR;
inL->setLastModified( modifiedCalendar );
inR = inL->clone();
inR->setIDStr( ":" );
inR->setCalID( 0 );// add to default cal
remote->addIncidence( inR );
}
}
}
} else {
++filteredOUT;
}
}
}
inL = el.next();
}
int delFut = 0;
int remRem = 0;
if ( mSyncManager->mWriteBackInFuture ) {
er = remote->rawIncidences();
remRem = er.count();
inR = er.first();
QDateTime dt;
QDateTime cur = QDateTime::currentDateTime().addDays( -(mSyncManager->mWriteBackInPast * 7) );
QDateTime end = QDateTime::currentDateTime().addDays( (mSyncManager->mWriteBackInFuture ) *7 );
while ( inR ) {
if ( inR->typeID() == todoID ) {
Todo * t = (Todo*)inR;
if ( t->hasDueDate() )
dt = t->dtDue();
else
dt = cur.addSecs( 62 );
}
else if (inR->typeID() == eventID ) {
bool ok;
dt = inR->getNextOccurence( cur, &ok );
if ( !ok )
dt = cur.addSecs( -62 );
}
else
dt = inR->dtStart();
if ( dt < cur || dt > end ) {
remote->deleteIncidence( inR );
++delFut;
}
inR = er.next();
}
}
bar.hide();
mLastCalendarSync = QDateTime::currentDateTime().addSecs( 1 );
if ( mMultiResourceSync ) {
remote->removeSyncInfo( "" ); //all
} else {
eventLSync->setReadOnly( false );
eventLSync->setDtStart( mLastCalendarSync );
eventRSync->setDtStart( mLastCalendarSync );
eventLSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) );
eventRSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) );
eventRSync->setLocation( i18n("Remote from: ")+mCurrentSyncName ) ;
eventLSync->setLocation(i18n("Local from: ") + mCurrentSyncName );
eventLSync->setReadOnly( true );
}
qDebug("KO: Normal sync: %d ",mGlobalSyncMode == SYNC_MODE_NORMAL );
if ( mGlobalSyncMode == SYNC_MODE_NORMAL && !mSyncManager->syncWithDesktop() && !mMultiResourceSync ) // kde is abnormal...
remote->addEvent( eventRSync );
else
delete eventRSync;
qDebug("KO: Sync with desktop %d ",mSyncManager->syncWithDesktop() );
QString mes;
mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n %d incoming filtered out\n %d outgoing filtered out\n"),addedEvent, addedEventR, changedLocal, changedRemote, deletedEventL, deletedEventR, filteredIN, filteredOUT );
QString delmess;
if ( delFut ) {
delmess.sprintf( i18n("%d items skipped on remote,\nbecause they are more\nthan %d weeks in the past or\nmore than %d weeks in the future.\nAfter skipping, remote has\n%d calendar/todo items."), delFut,mSyncManager->mWriteBackInPast,mSyncManager->mWriteBackInFuture, remRem-delFut);
mes += delmess;
}
mes = i18n("Local calendar changed!\n") +mes;
mCalendar->checkAlarmForIncidence( 0, true );
qDebug( mes );
if ( mSyncManager->mShowSyncSummary ) {
if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel(this, mes,
i18n("KO/Pi Synchronization"),i18n("Write back"))) {
qDebug("KO: WB cancelled ");
mSyncManager->mWriteBackFile = false;
return syncOK;
}
}
return syncOK;
}
void CalendarView::setSyncDevice( QString s )
{
mCurrentSyncDevice= s;
}
void CalendarView::setSyncName( QString s )
{
mCurrentSyncName= s;
}
bool CalendarView::syncCalendar(QString filename, int mode)
{
//qDebug("syncCalendar %s ", filename.latin1());
mGlobalSyncMode = SYNC_MODE_NORMAL;
CalendarLocal* calendar = new CalendarLocal();
calendar->setTimeZoneId(KPimGlobalPrefs::instance()->mTimeZoneId);
FileStorage* storage = new FileStorage( calendar );
bool syncOK = false;
storage->setFileName( filename );
// qDebug("loading ... ");
if ( storage->load() ) {
getEventViewerDialog()->setSyncMode( true );
syncOK = synchronizeCalendar( mCalendar, calendar, mode );
getEventViewerDialog()->setSyncMode( false );
if ( syncOK ) {
if ( mSyncManager->mWriteBackFile )
{
storage->setSaveFormat( new ICalFormat() );
storage->save();
}
}
setModified( true );
}
delete storage;
delete calendar;
if ( syncOK )
updateView();
return syncOK;
}
void CalendarView::syncExternal( int mode )
{
mGlobalSyncMode = SYNC_MODE_EXTERNAL;
qApp->processEvents();
CalendarLocal* calendar = new CalendarLocal();
calendar->setTimeZoneId(KPimGlobalPrefs::instance()->mTimeZoneId);
bool syncOK = false;
bool loadSuccess = false;
PhoneFormat* phoneFormat = 0;
emit tempDisableBR(true);
#ifndef DESKTOP_VERSION
SharpFormat* sharpFormat = 0;
if ( mode == 0 ) { // sharp
sharpFormat = new SharpFormat () ;
loadSuccess = sharpFormat->load( calendar, mCalendar );
} else
#endif
if ( mode == 1 ) { // phone
phoneFormat = new PhoneFormat (mCurrentSyncDevice,
mSyncManager->mPhoneDevice,
mSyncManager->mPhoneConnection,
mSyncManager->mPhoneModel);
loadSuccess = phoneFormat->load( calendar,mCalendar);
} else {
emit tempDisableBR(false);
return;
}
if ( loadSuccess ) {
getEventViewerDialog()->setSyncMode( true );
syncOK = synchronizeCalendar( mCalendar, calendar, mSyncManager->mSyncAlgoPrefs );
getEventViewerDialog()->setSyncMode( false );
qApp->processEvents();
if ( syncOK ) {
if ( mSyncManager->mWriteBackFile )
{
QPtrList<Incidence> iL = mCalendar->rawIncidences();
Incidence* inc = iL.first();
if ( phoneFormat ) {
while ( inc ) {
inc->removeID(mCurrentSyncDevice);
inc = iL.next();
}
}
#ifndef DESKTOP_VERSION
if ( sharpFormat )
sharpFormat->save(calendar);
#endif
if ( phoneFormat )
phoneFormat->save(calendar);
iL = calendar->rawIncidences();
inc = iL.first();
Incidence* loc;
while ( inc ) {
if ( inc->tempSyncStat() == SYNC_TEMPSTATE_NEW_ID ) {
loc = mCalendar->incidence(inc->uid() );
if ( loc ) {
loc->setID(mCurrentSyncDevice, inc->getID(mCurrentSyncDevice) );
loc->setCsum( mCurrentSyncDevice, inc->getCsum(mCurrentSyncDevice) );
}
}
inc = iL.next();
}
Incidence* lse = getLastSyncEvent();
if ( lse ) {
lse->setReadOnly( false );
lse->setDescription( "" );
lse->setReadOnly( true );
}
}
} else {
topLevelWidget()->setCaption( i18n("Sync cancelled or failed.") );
}
setModified( true );
} else {
QString question = i18n("Sorry, the database access\ncommand failed!\n\nNothing synced!\n") ;
QMessageBox::information( 0, i18n("KO/Pi Import - ERROR"),
question, i18n("Ok")) ;
}
delete calendar;
updateView();
emit tempDisableBR(false);
return ;//syncOK;
}
bool CalendarView::importBday()
{
#ifndef KORG_NOKABC
#ifdef DESKTOP_VERSION
int curCal = mCalendar->defaultCalendar();
int bd = mCalEditView->getBirtdayID();
if ( bd == 0 )
return false;
mCalendar->setDefaultCalendar( bd );
KABC::StdAddressBook* AddressBook = KABC::StdAddressBook::self( true );
KABC::AddressBook::Iterator it;
int count = 0;
for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) {
++count;
}
QProgressBar bar(count,0 );
int w = 300;
if ( QApplication::desktop()->width() < 320 )
w = 220;
int h = bar.sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
bar.show();
bar.setCaption (i18n("Reading addressbook - close to abort!") );
qApp->processEvents();
count = 0;
int addCount = 0;
KCal::Attendee* a = 0;
for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) {
if ( ! bar.isVisible() )
return false;
bar.setProgress( count++ );
qApp->processEvents();
//qDebug("add BDay %s %s", (*it).realName().latin1(),(*it).birthday().date().toString().latin1() );
if ( (*it).birthday().date().isValid() ){
a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ;
if ( addAnniversary( (*it).birthday().date(), (*it).assembledName(), a, true ) )
++addCount;
}
QDate anni = KGlobal::locale()->readDate( (*it).custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d");
if ( anni.isValid() ){
a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ;
if ( addAnniversary( anni, (*it).assembledName(), a, false ) )
++addCount;
}
}
mCalendar->setDefaultCalendar( curCal );
updateView();
topLevelWidget()->setCaption(QString::number( addCount )+ i18n(" birthdays/anniversaries added!"));
#else //DESKTOP_VERSION
ExternalAppHandler::instance()->requestBirthdayListFromKAPI("QPE/Application/kopi", this->name() /* name is here the unique uid*/);
// the result should now arrive through method insertBirthdays
#endif //DESKTOP_VERSION
#endif //KORG_NOKABC
return true;
}
// This method will be called from Ka/Pi as a response to requestBirthdayListFromKAPI
void CalendarView::insertBirthdays(const QString& uid, const QStringList& birthdayList,
const QStringList& anniversaryList, const QStringList& realNameList,
const QStringList& emailList, const QStringList& assembledNameList,
const QStringList& uidList)
{
//qDebug("KO::CalendarView::insertBirthdays");
if (uid == this->name())
{
int curCal = mCalendar->defaultCalendar();
int bd = mCalEditView->getBirtdayID();
if ( bd == 0 )
return;
mCalendar->setDefaultCalendar( bd );
int count = birthdayList.count();
int addCount = 0;
KCal::Attendee* a = 0;
//qDebug("CalView 1 %i", count);
QProgressBar bar(count,0 );
int w = 300;
if ( QApplication::desktop()->width() < 320 )
w = 220;
int h = bar.sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
bar.show();
bar.setCaption (i18n("inserting birthdays - close to abort!") );
qApp->processEvents();
diff --git a/libkcal/calendar.h b/libkcal/calendar.h
index 0a94914..66836a1 100644
--- a/libkcal/calendar.h
+++ b/libkcal/calendar.h
@@ -1,383 +1,384 @@
/*
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 CALENDAR_H
#define CALENDAR_H
#include <qobject.h>
#include <qstring.h>
#include <qdatetime.h>
#include <qptrlist.h>
#include <qdict.h>
#include "customproperties.h"
#include "event.h"
#include "todo.h"
#include "journal.h"
#include "calfilter.h"
//#define _TIME_ZONE "-0500" /* hardcoded, overridden in config file. */
class KConfig;
namespace KCal {
/**
This is the main "calendar" object class for KOrganizer. It holds
information like all appointments/events, user information, etc. etc.
one calendar is associated with each CalendarView (@see calendarview.h).
This is an abstract base class defining the interface to a calendar. It is
implemented by subclasses like @see CalendarLocal, which use different
methods to store and access the data.
Ownership of events etc. is handled by the following policy: As soon as an
event (or any other subclass of IncidenceBase) object is added to the
Calendar by addEvent() it is owned by the Calendar object. The Calendar takes
care of deleting it. All Events returned by the query functions are returned
as pointers, that means all changes to the returned events are immediately
visible in the Calendar. You shouldn't delete any Event object you get from
Calendar.
*/
class Calendar : public QObject, public CustomProperties,
public IncidenceBase::Observer
{
Q_OBJECT
public:
Calendar();
Calendar(const QString &timeZoneId);
virtual ~Calendar();
Incidence * undoIncidence() { return mUndoIncidence; };
bool undoDeleteIncidence();
void deleteIncidence(Incidence *in);
void resetTempSyncStat();
void resetPilotStat(int id);
/**
Clears out the current calendar, freeing all used memory etc.
*/
virtual void close() = 0;
virtual void addCalendar( Calendar* ) = 0;
virtual bool addCalendarFile( QString name, int id ) = 0;
virtual bool mergeCalendarFile( QString name ) = 0;
virtual Incidence* incidenceForUid( const QString& uid, bool doNotCheckDuplicates ) = 0;
virtual void setSyncEventsReadOnly() = 0;
virtual void setSyncEventsEnabled() = 0;
virtual void stopAllTodos() = 0;
virtual void clearUndo( Incidence * newUndo );
/**
Sync changes in memory to persistant storage.
*/
virtual void save() = 0;
virtual QPtrList<Event> getExternLastSyncEvents() = 0;
virtual void removeSyncInfo( QString syncProfile) = 0;
virtual bool isSaving() { return false; }
/**
Return the owner of the calendar's full name.
*/
const QString &getOwner() const;
/**
Set the owner of the calendar. Should be owner's full name.
*/
void setOwner( const QString &os );
/**
Return the email address of the calendar owner.
*/
const QString &getEmail();
/**
Set the email address of the calendar owner.
*/
void setEmail( const QString & );
/**
Set time zone from a timezone string (e.g. -2:00)
*/
void setTimeZone( const QString &tz );
/**
Set time zone from a minutes value (e.g. -60)
*/
void setTimeZone( int tz );
/**
Return time zone as offest in minutes.
*/
int getTimeZone() const;
/**
Compute an ISO 8601 format string from the time zone.
*/
QString getTimeZoneStr() const;
/**
Set time zone id (see /usr/share/zoneinfo/zone.tab for list of legal
values).
*/
void setTimeZoneId( const QString & );
/**
Return time zone id.
*/
QString timeZoneId() const;
/**
Use local time, not UTC or a time zone.
*/
void setLocalTime();
/**
Return whether local time is being used.
*/
bool isLocalTime() const;
/**
Add an incidence to calendar.
@return true on success, false on error.
*/
virtual bool addIncidence( Incidence * );
// Adds an incidence and all relatedto incidences to the cal
void addIncidenceBranch( Incidence * );
/**
Return filtered list of all incidences of this calendar.
*/
virtual QPtrList<Incidence> incidences();
/**
Return unfiltered list of all incidences of this calendar.
*/
virtual QPtrList<Incidence> rawIncidences();
/**
Adds a Event to this calendar object.
@param anEvent a pointer to the event to add
@return true on success, false on error.
*/
virtual bool addEventNoDup( Event *event ) = 0;
virtual bool addAnniversaryNoDup( Event *event ) = 0;
virtual bool addEvent( Event *anEvent ) = 0;
/**
Delete event from calendar.
*/
virtual void deleteEvent( Event * ) = 0;
/**
Retrieves an event on the basis of the unique string ID.
*/
virtual Event *event( const QString &UniqueStr ) = 0;
virtual Event *event( QString, QString ) = 0;
/**
Builds and then returns a list of all events that match for the
date specified. useful for dayView, etc. etc.
The calendar filter is applied.
*/
QPtrList<Event> events( const QDate &date, bool sorted = false);
/**
Get events, which occur on the given date.
The calendar filter is applied.
*/
QPtrList<Event> events( const QDateTime &qdt );
/**
Get events in a range of dates. If inclusive is set to true, only events
are returned, which are completely included in the range.
The calendar filter is applied.
*/
QPtrList<Event> events( const QDate &start, const QDate &end,
bool inclusive = false);
/**
Return filtered list of all events in calendar.
*/
virtual QPtrList<Event> events();
/**
Return unfiltered list of all events in calendar.
*/
virtual QPtrList<Event> rawEvents() = 0;
/**
Add a todo to the todolist.
@return true on success, false on error.
*/
virtual bool addTodo( Todo *todo ) = 0;
virtual bool addTodoNoDup( Todo *todo ) = 0;
/**
Remove a todo from the todolist.
*/
virtual void deleteTodo( Todo * ) = 0;
virtual void deleteJournal( Journal * ) = 0;
/**
Return filterd list of todos.
*/
virtual QPtrList<Todo> todos();
/**
Searches todolist for an event with this unique string identifier,
returns a pointer or null.
*/
virtual Todo *todo( const QString &uid ) = 0;
virtual Todo *todo( QString, QString ) = 0;
/**
Returns list of todos due on the specified date.
*/
virtual QPtrList<Todo> todos( const QDate &date ) = 0;
/**
Return unfiltered list of todos.
*/
virtual QPtrList<Todo> rawTodos() = 0;
/**
Add a Journal entry to calendar.
@return true on success, false on error.
*/
virtual bool addJournal( Journal * ) = 0;
/**
Return Journal for given date.
*/
virtual Journal *journal( const QDate & ) = 0;
virtual QPtrList<Journal> journals4Date( const QDate & ) = 0;
/**
Return Journal with given UID.
*/
virtual Journal *journal( const QString &UID ) = 0;
/**
Return list of all Journal entries.
*/
virtual QPtrList<Journal> journals() = 0;
/**
Searches all incidence types for an incidence with this unique
string identifier, returns a pointer or null.
*/
Incidence* incidence( const QString&UID );
/**
Setup relations for an incidence.
*/
virtual void setupRelations( Incidence * );
/**
Remove all relations to an incidence
*/
virtual void removeRelations( Incidence * );
/**
Set calendar filter, which filters events for the events() functions.
The Filter object is owned by the caller.
*/
void setFilter( CalFilter * );
/**
Return calendar filter.
*/
CalFilter *filter();
virtual QDateTime nextAlarm( int daysTo ) = 0;
virtual QString nextSummary( ) const = 0;
virtual void reInitAlarmSettings() = 0;
virtual QDateTime nextAlarmEventDateTime() const = 0;
virtual void checkAlarmForIncidence( Incidence *, bool ) = 0;
/**
Return all alarms, which ocur in the given time interval.
*/
virtual Alarm::List alarms( const QDateTime &from,
const QDateTime &to ) = 0;
class Observer {
public:
virtual void calendarModified( bool, Calendar * ) = 0;
};
void registerObserver( Observer * );
void setModified( bool );
/**
Set product id returned by loadedProductId(). This function is only
useful for the calendar loading code.
*/
void setLoadedProductId( const QString & );
/**
Return product id taken from file that has been loaded. Returns
QString::null, if no calendar has been loaded.
*/
QString loadedProductId();
int defaultCalendar();
void setDontDeleteIncidencesOnClose ();
public slots:
void setDefaultCalendar( int );
virtual void setCalendarEnabled( int id, bool enable ) = 0;
+ virtual void setAllCalendarEnabled( bool enable ) = 0;
virtual void setAlarmEnabled( int id, bool enable ) = 0;
virtual void setReadOnly( int id, bool enable ) = 0;
virtual void setDefaultCalendarEnabledOnly() = 0;
virtual void setCalendarRemove( int id ) = 0;
virtual void getIncidenceCount( int calId, int& events, int & todos, int & journals) = 0;
signals:
void calendarChanged();
void calendarSaved();
void calendarLoaded();
void addAlarm(const QDateTime &qdt, const QString &noti );
void removeAlarm(const QDateTime &qdt, const QString &noti );
protected:
/**
Get unfiltered events, which occur on the given date.
*/
virtual QPtrList<Event> rawEventsForDate( const QDateTime &qdt ) = 0;
/**
Get unfiltered events, which occur on the given date.
*/
virtual QPtrList<Event> rawEventsForDate( const QDate &date,
bool sorted = false ) = 0;
/**
Get events in a range of dates. If inclusive is set to true, only events
are returned, which are completely included in the range.
*/
virtual QPtrList<Event> rawEvents( const QDate &start, const QDate &end,
bool inclusive = false ) = 0;
Incidence *mNextAlarmIncidence;
Incidence *mUndoIncidence;
int mDefaultCalendar;
bool mDeleteIncidencesOnClose;
private:
void init();
QString mOwner; // who the calendar belongs to
QString mOwnerEmail; // email address of the owner
int mTimeZone; // timezone OFFSET from GMT (MINUTES)
bool mLocalTime; // use local time, not UTC or a time zone
CalFilter *mFilter;
CalFilter *mDefaultFilter;
QString mTimeZoneId;
Observer *mObserver;
bool mNewObserver;
bool mModified;
QString mLoadedProductId;
// This list is used to put together related todos
QDict<Incidence> mOrphans;
QDict<Incidence> mOrphanUids;
};
}
#endif
diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp
index 45e3128..2a57724 100644
--- a/libkcal/calendarlocal.cpp
+++ b/libkcal/calendarlocal.cpp
@@ -1,1056 +1,1079 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brown
Copyright (c) 2001,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.
*/
#include <qdatetime.h>
#include <qstring.h>
#include <qptrlist.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include "vcaldrag.h"
#include "vcalformat.h"
#include "icalformat.h"
#include "exceptions.h"
#include "incidence.h"
#include "journal.h"
#include "filestorage.h"
#include "calfilter.h"
#include "calendarlocal.h"
// #ifndef DESKTOP_VERSION
// #include <qtopia/alarmserver.h>
// #endif
using namespace KCal;
CalendarLocal::CalendarLocal()
: Calendar()
{
init();
}
CalendarLocal::CalendarLocal(const QString &timeZoneId)
: Calendar(timeZoneId)
{
init();
}
void CalendarLocal::init()
{
mNextAlarmIncidence = 0;
}
CalendarLocal::~CalendarLocal()
{
registerObserver( 0 );
if ( mDeleteIncidencesOnClose )
close();
}
bool CalendarLocal::mergeCalendarFile( QString name )
{
CalendarLocal calendar( timeZoneId() );
calendar.setDefaultCalendar( 1 );
if ( calendar.load( name ) ) {
mergeCalendar( &calendar );
return true;
}
return false;
}
Incidence* CalendarLocal::incidenceForUid( const QString& uid , bool doNotCheckDuplicates)
{
Todo *todo;;
Incidence *retVal = 0;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->uid() == uid ) {
if ( doNotCheckDuplicates ) return todo;
if ( retVal ) {
if ( retVal->calID() > todo->calID() ) {
retVal = todo;
}
} else {
retVal = todo;
}
}
}
if ( retVal ) return retVal;
Event *event;
for ( event = mEventList.first(); event; event = mEventList.next() ) {
if ( event->uid() == uid ) {
if ( doNotCheckDuplicates ) return event;
if ( retVal ) {
if ( retVal->calID() > event->calID() ) {
retVal = event;
}
} else {
retVal = event;
}
}
}
if ( retVal ) return retVal;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->uid() == uid ) {
if ( doNotCheckDuplicates ) return it;
if ( retVal ) {
if ( retVal->calID() > it->calID() ) {
retVal = it;
}
} else {
retVal = it;
}
}
return retVal;
}
bool CalendarLocal::mergeCalendar( Calendar* remote )
{
// 1 look for raw inc in local
// if inc not in remote, delete in local
// 2 look for raw inc in remote
// if inc in local, replace it
// if not in local, add it to default calendar
QPtrList<Incidence> localInc = rawIncidences();
Incidence* inL = localInc.first();
while ( inL ) {
if ( ! inL->isReadOnly () )
if ( !remote->incidenceForUid( inL->uid(), true ))
deleteIncidence( inL );
inL = localInc.next();
}
QPtrList<Incidence> er = remote->rawIncidences();
Incidence* inR = er.first();
while ( inR ) {
inL = incidenceForUid( inR->uid(),false );
if ( inL ) {
if ( ! inL->isReadOnly () || inL->uid().left(15) == QString("last-syncEvent-") ) {
int calID = inL->calID();
deleteIncidence( inL );
inL = inR->clone();
inL->setCalID( calID );
addIncidence( inL );
}
} else {
inL = inR->clone();
inL->setCalID( 0 );// add to default cal
addIncidence( inL );
}
inR = er.next();
}
return true;
}
bool CalendarLocal::addCalendarFile( QString name, int id )
{
CalendarLocal calendar( timeZoneId() );
calendar.setDefaultCalendar( id );
if ( calendar.load( name ) ) {
addCalendar( &calendar );
return true;
}
return false;
}
void CalendarLocal::setSyncEventsEnabled()
{
Event * ev;
ev = mEventList.first();
while ( ev ) {
if ( ev->uid().left(15) == QString("last-syncEvent-") )
ev->setCalEnabled( true );
ev = mEventList.next();
}
}
void CalendarLocal::setSyncEventsReadOnly()
{
Event * ev;
ev = mEventList.first();
while ( ev ) {
if ( ev->uid().left(15) == QString("last-syncEvent-") ) {
ev->setReadOnly( true );
- ev->setCalID( 1 );
}
ev = mEventList.next();
}
}
+
void CalendarLocal::addCalendar( Calendar* cal )
{
cal->setDontDeleteIncidencesOnClose();
+ setSyncEventsEnabled();
{
QPtrList<Event> EventList = cal->rawEvents();
+ QPtrList<Event> el;
Event * ev = EventList.first();
while ( ev ) {
+ if ( ev->uid().left( 15 ) == QString("last-syncEvent-") ) {
+ Event * se = event( ev->uid() );
+ if ( se )
+ el.append( se );
+ }
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mEventList.append( ev );
ev = EventList.next();
}
+ for ( ev = el.first(); ev; ev = el.next() ) {
+ deleteIncidence ( ev );
+ }
}
{
QPtrList<Todo> TodoList = cal->rawTodos();
Todo * ev = TodoList.first();
while ( ev ) {
QString rel = ev->relatedToUid();
if ( !rel.isEmpty() ){
ev->setRelatedTo ( 0 );
ev->setRelatedToUid( rel );
}
ev = TodoList.next();
}
//TodoList = cal->rawTodos();
ev = TodoList.first();
while ( ev ) {
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mTodoList.append( ev );
setupRelations( ev );
ev = TodoList.next();
}
}
{
QPtrList<Journal> JournalList = cal->journals();
Journal * ev = JournalList.first();
while ( ev ) {
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mJournalList.append( ev );
ev = JournalList.next();
}
}
setModified( true );
}
bool CalendarLocal::load( const QString &fileName )
{
FileStorage storage( this, fileName );
return storage.load();
}
bool CalendarLocal::save( const QString &fileName, CalFormat *format )
{
FileStorage storage( this, fileName, format );
return storage.save();
}
void CalendarLocal::stopAllTodos()
{
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
it->setRunning( false );
}
void CalendarLocal::close()
{
Todo * i;
for( i = mTodoList.first(); i; i = mTodoList.next() ) i->setRunning(false);
mEventList.setAutoDelete( true );
mTodoList.setAutoDelete( true );
mJournalList.setAutoDelete( true );
mEventList.clear();
mTodoList.clear();
mJournalList.clear();
mEventList.setAutoDelete( false );
mTodoList.setAutoDelete( false );
mJournalList.setAutoDelete( false );
setModified( false );
}
bool CalendarLocal::addAnniversaryNoDup( Event *event )
{
QString cat;
bool isBirthday = true;
if( event->categoriesStr() == i18n( "Anniversary" ) ) {
isBirthday = false;
cat = i18n( "Anniversary" );
} else if( event->categoriesStr() == i18n( "Birthday" ) ) {
isBirthday = true;
cat = i18n( "Birthday" );
} else {
qDebug("addAnniversaryNoDup called without fitting category! ");
return false;
}
Event * eve;
for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
if ( !(eve->categories().contains( cat ) ))
continue;
// now we have an event with fitting category
if ( eve->dtStart().date() != event->dtStart().date() )
continue;
// now we have an event with fitting category+date
if ( eve->summary() != event->summary() )
continue;
// now we have an event with fitting category+date+summary
return false;
}
return addEvent( event );
}
bool CalendarLocal::addEventNoDup( Event *event )
{
Event * eve;
for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
if ( *eve == *event ) {
//qDebug("CalendarLocal::Duplicate event found! Not inserted! ");
return false;
}
}
return addEvent( event );
}
bool CalendarLocal::addEvent( Event *event )
{
insertEvent( event );
event->registerObserver( this );
setModified( true );
if ( event->calID() == 0 )
event->setCalID( mDefaultCalendar );
event->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteEvent( Event *event )
{
clearUndo(event);
if ( mEventList.removeRef( event ) ) {
setModified( true );
}
}
Event *CalendarLocal::event( const QString &uid )
{
Event *event;
Event *retVal = 0;
for ( event = mEventList.first(); event; event = mEventList.next() ) {
if ( event->calEnabled() && event->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > event->calID() ) {
retVal = event;
}
} else {
retVal = event;
}
}
}
return retVal;
}
bool CalendarLocal::addTodoNoDup( Todo *todo )
{
Todo * eve;
for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) {
if ( *eve == *todo ) {
//qDebug("duplicate todo found! not inserted! ");
return false;
}
}
return addTodo( todo );
}
bool CalendarLocal::addTodo( Todo *todo )
{
mTodoList.append( todo );
todo->registerObserver( this );
// Set up subtask relations
setupRelations( todo );
setModified( true );
if ( todo->calID() == 0 )
todo->setCalID( mDefaultCalendar );
todo->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteTodo( Todo *todo )
{
// Handle orphaned children
removeRelations( todo );
clearUndo(todo);
if ( mTodoList.removeRef( todo ) ) {
setModified( true );
}
}
QPtrList<Todo> CalendarLocal::rawTodos()
{
QPtrList<Todo> el;
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
Todo *CalendarLocal::todo( QString syncProf, QString id )
{
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo;
}
return 0;
}
void CalendarLocal::removeSyncInfo( QString syncProfile)
{
QPtrList<Incidence> all = rawIncidences() ;
Incidence *inc;
for ( inc = all.first(); inc; inc = all.next() ) {
inc->removeID( syncProfile );
}
if ( syncProfile.isEmpty() ) {
QPtrList<Event> el;
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->uid().left( 15 ) == QString("last-syncEvent-") )
el.append( todo );
}
for ( todo = el.first(); todo; todo = el.next() ) {
deleteIncidence ( todo );
}
} else {
Event *lse = event( "last-syncEvent-"+ syncProfile);
if ( lse )
deleteIncidence ( lse );
}
}
QPtrList<Event> CalendarLocal::getExternLastSyncEvents()
{
QPtrList<Event> el;
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->uid().left( 15 ) == QString("last-syncEvent-") )
if ( todo->summary().left(3) == "E: " )
el.append( todo );
}
return el;
}
Event *CalendarLocal::event( QString syncProf, QString id )
{
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo;
}
return 0;
}
Todo *CalendarLocal::todo( const QString &uid )
{
Todo *todo;
Todo *retVal = 0;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->calEnabled() && todo->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > todo->calID() ) {
retVal = todo;
}
} else {
retVal = todo;
}
}
}
return retVal;
}
void CalendarLocal::getIncidenceCount( int calId, int& events, int & todos, int & journals)
{
events = 0;
todos = 0;
journals = 0;
{
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->calID() == calId )
++todos;
}
}
{
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->calID() == calId )
++events;
}
}
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == calId ) ++journals;
}
QString CalendarLocal::nextSummary() const
{
return mNextSummary;
}
QDateTime CalendarLocal::nextAlarmEventDateTime() const
{
return mNextAlarmEventDateTime;
}
void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted)
{
//mNextAlarmIncidence
//mNextAlarmDateTime
//return mNextSummary;
//return mNextAlarmEventDateTime;
bool newNextAlarm = false;
bool computeNextAlarm = false;
bool ok;
int offset;
QDateTime nextA;
// QString nextSum;
//QDateTime nextEvent;
if ( mNextAlarmIncidence == 0 || incidence == 0 ) {
computeNextAlarm = true;
} else {
if ( ! deleted ) {
nextA = incidence->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( nextA < mNextAlarmDateTime ) {
deRegisterAlarm();
mNextAlarmDateTime = nextA;
mNextSummary = incidence->summary();
mNextAlarmEventDateTime = nextA.addSecs(offset ) ;
mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
newNextAlarm = true;
mNextAlarmIncidence = incidence;
} else {
if ( incidence == mNextAlarmIncidence ) {
computeNextAlarm = true;
}
}
} else {
if ( mNextAlarmIncidence == incidence ) {
computeNextAlarm = true;
}
}
} else { // deleted
if ( incidence == mNextAlarmIncidence ) {
computeNextAlarm = true;
}
}
}
if ( computeNextAlarm ) {
deRegisterAlarm();
nextA = nextAlarm( 1000 );
if (! mNextAlarmIncidence ) {
return;
}
newNextAlarm = true;
}
if ( newNextAlarm )
registerAlarm();
}
QString CalendarLocal:: getAlarmNotification()
{
QString ret;
// this should not happen
if (! mNextAlarmIncidence )
return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString;
Alarm* alarm = mNextAlarmIncidence->alarms().first();
if ( alarm->type() == Alarm::Procedure ) {
ret = "proc_alarm" + alarm->programFile()+"+++";
} else {
ret = "audio_alarm" +alarm->audioFile() +"+++";
}
ret += "cal_alarm"+ mNextSummary.left( 25 );
if ( mNextSummary.length() > 25 )
ret += "\n" + mNextSummary.mid(25, 25 );
ret+= "\n"+mNextAlarmEventDateTimeString;
return ret;
}
void CalendarLocal::registerAlarm()
{
mLastAlarmNotificationString = getAlarmNotification();
// qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() );
emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
// #ifndef DESKTOP_VERSION
// AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() );
// #endif
}
void CalendarLocal::deRegisterAlarm()
{
if ( mLastAlarmNotificationString.isNull() )
return;
//qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() );
emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
mNextAlarmEventDateTime = QDateTime();
// #ifndef DESKTOP_VERSION
// AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() );
// #endif
}
QPtrList<Todo> CalendarLocal::todos( const QDate &date )
{
QPtrList<Todo> todos;
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( !todo->calEnabled() ) continue;
if ( todo->hasDueDate() && todo->dtDue().date() == date ) {
todos.append( todo );
}
}
filter()->apply( &todos );
return todos;
}
void CalendarLocal::reInitAlarmSettings()
{
if ( !mNextAlarmIncidence ) {
nextAlarm( 1000 );
}
deRegisterAlarm();
mNextAlarmIncidence = 0;
checkAlarmForIncidence( 0, false );
}
QDateTime CalendarLocal::nextAlarm( int daysTo )
{
QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo );
QDateTime start = QDateTime::currentDateTime().addSecs( 30 );
QDateTime next;
Event *e;
bool ok;
bool found = false;
int offset;
mNextAlarmIncidence = 0;
for( e = mEventList.first(); e; e = mEventList.next() ) {
if ( !e->calEnabled() ) continue;
next = e->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( next < nextA ) {
nextA = next;
found = true;
mNextSummary = e->summary();
mNextAlarmEventDateTime = next.addSecs(offset ) ;
mNextAlarmIncidence = (Incidence *) e;
}
}
}
Todo *t;
for( t = mTodoList.first(); t; t = mTodoList.next() ) {
if ( !t->calEnabled() ) continue;
next = t->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( next < nextA ) {
nextA = next;
found = true;
mNextSummary = t->summary();
mNextAlarmEventDateTime = next.addSecs(offset );
mNextAlarmIncidence = (Incidence *) t;
}
}
}
if ( mNextAlarmIncidence ) {
mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
mNextAlarmDateTime = nextA;
}
return nextA;
}
Alarm::List CalendarLocal::alarmsTo( const QDateTime &to )
{
return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to );
}
Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to )
{
Alarm::List alarms;
Event *e;
for( e = mEventList.first(); e; e = mEventList.next() ) {
if ( !e->calEnabled() ) continue;
if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to );
else appendAlarms( alarms, e, from, to );
}
Todo *t;
for( t = mTodoList.first(); t; t = mTodoList.next() ) {
if ( !t->calEnabled() ) continue;
appendAlarms( alarms, t, from, to );
}
return alarms;
}
void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence,
const QDateTime &from, const QDateTime &to )
{
QPtrList<Alarm> alarmList = incidence->alarms();
Alarm *alarm;
for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
// kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text()
// << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl;
if ( alarm->enabled() ) {
if ( alarm->time() >= from && alarm->time() <= to ) {
alarms.append( alarm );
}
}
}
}
void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms,
Incidence *incidence,
const QDateTime &from,
const QDateTime &to )
{
QPtrList<Alarm> alarmList = incidence->alarms();
Alarm *alarm;
QDateTime qdt;
for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
if (incidence->recursOn(from.date())) {
qdt.setTime(alarm->time().time());
qdt.setDate(from.date());
}
else qdt = alarm->time();
// qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1());
if ( alarm->enabled() ) {
if ( qdt >= from && qdt <= to ) {
alarms.append( alarm );
}
}
}
}
/****************************** PROTECTED METHODS ****************************/
// after changes are made to an event, this should be called.
void CalendarLocal::update( IncidenceBase *incidence )
{
incidence->setSyncStatus( Event::SYNCMOD );
incidence->setLastModified( QDateTime::currentDateTime() );
// we should probably update the revision number here,
// or internally in the Event itself when certain things change.
// need to verify with ical documentation.
setModified( true );
}
void CalendarLocal::insertEvent( Event *event )
{
if ( mEventList.findRef( event ) < 0 ) mEventList.append( event );
}
QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted )
{
QPtrList<Event> eventList;
Event *event;
for( event = mEventList.first(); event; event = mEventList.next() ) {
if ( !event->calEnabled() ) continue;
if ( event->doesRecur() ) {
if ( event->isMultiDay() ) {
int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() );
int i;
for ( i = 0; i <= extraDays; i++ ) {
if ( event->recursOn( qd.addDays( -i ) ) ) {
eventList.append( event );
break;
}
}
} else {
if ( event->recursOn( qd ) )
eventList.append( event );
}
} else {
if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) {
eventList.append( event );
}
}
}
if ( !sorted ) {
return eventList;
}
// kdDebug(5800) << "Sorting events for date\n" << endl;
// now, we have to sort it based on dtStart.time()
QPtrList<Event> eventListSorted;
Event *sortEvent;
for ( event = eventList.first(); event; event = eventList.next() ) {
sortEvent = eventListSorted.first();
int i = 0;
while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() )
{
i++;
sortEvent = eventListSorted.next();
}
eventListSorted.insert( i, event );
}
return eventListSorted;
}
QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end,
bool inclusive )
{
Event *event = 0;
QPtrList<Event> eventList;
// Get non-recurring events
for( event = mEventList.first(); event; event = mEventList.next() ) {
if ( !event->calEnabled() ) continue;
if ( event->doesRecur() ) {
QDate rStart = event->dtStart().date();
bool found = false;
if ( inclusive ) {
if ( rStart >= start && rStart <= end ) {
// Start date of event is in range. Now check for end date.
// if duration is negative, event recurs forever, so do not include it.
if ( event->recurrence()->duration() == 0 ) { // End date set
QDate rEnd = event->recurrence()->endDate();
if ( rEnd >= start && rEnd <= end ) { // End date within range
found = true;
}
} else if ( event->recurrence()->duration() > 0 ) { // Duration set
// TODO: Calculate end date from duration. Should be done in Event
// For now exclude all events with a duration.
}
}
} else {
bool founOne;
QDate next = event->getNextOccurence( start, &founOne ).date();
if ( founOne ) {
if ( next <= end ) {
found = true;
}
}
/*
// crap !!!
if ( rStart <= end ) { // Start date not after range
if ( rStart >= start ) { // Start date within range
found = true;
} else if ( event->recurrence()->duration() == -1 ) { // Recurs forever
found = true;
} else if ( event->recurrence()->duration() == 0 ) { // End date set
QDate rEnd = event->recurrence()->endDate();
if ( rEnd >= start && rEnd <= end ) { // End date within range
found = true;
}
} else { // Duration set
// TODO: Calculate end date from duration. Should be done in Event
// For now include all events with a duration.
found = true;
}
}
*/
}
if ( found ) eventList.append( event );
} else {
QDate s = event->dtStart().date();
QDate e = event->dtEnd().date();
if ( inclusive ) {
if ( s >= start && e <= end ) {
eventList.append( event );
}
} else {
if ( ( e >= start && s <= end ) ) {
eventList.append( event );
}
}
}
}
return eventList;
}
QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt )
{
return rawEventsForDate( qdt.date() );
}
QPtrList<Event> CalendarLocal::rawEvents()
{
QPtrList<Event> el;
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
bool CalendarLocal::addJournal(Journal *journal)
{
mJournalList.append(journal);
journal->registerObserver( this );
setModified( true );
if ( journal->calID() == 0 )
journal->setCalID( mDefaultCalendar );
journal->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteJournal( Journal *journal )
{
clearUndo(journal);
if ( mJournalList.removeRef(journal) ) {
setModified( true );
}
}
QPtrList<Journal> CalendarLocal::journals4Date( const QDate & date )
{
QPtrList<Journal> el;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->dtStart().date() == date) el.append( it );
return el;
}
Journal *CalendarLocal::journal( const QDate &date )
{
// kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->dtStart().date() == date )
return it;
return 0;
}
Journal *CalendarLocal::journal( const QString &uid )
{
Journal * retVal = 0;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > it->calID() ) {
retVal = it;
}
} else {
retVal = it;
}
}
return retVal;
}
QPtrList<Journal> CalendarLocal::journals()
{
QPtrList<Journal> el;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
void CalendarLocal::setCalendarRemove( int id )
{
{
QPtrList<Event> EventList = mEventList;
Event * ev = EventList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteEvent( ev );
ev = EventList.next();
}
}
{
QPtrList<Todo> TodoList = mTodoList;
Todo * ev = TodoList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteTodo( ev );
ev = TodoList.next();
}
}
{
QPtrList<Journal> JournalList = mJournalList;
Journal * ev = JournalList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteJournal( ev );
ev = JournalList.next();
}
}
clearUndo(0);
}
+void CalendarLocal::setAllCalendarEnabled( bool enable )
+{
+ for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
+ it->setCalEnabled( enable );
+
+ for ( Event *it = mEventList.first(); it; it = mEventList.next() )
+ it->setCalEnabled( enable );
+
+ for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
+ it->setCalEnabled( enable );
+
+
+}
void CalendarLocal::setCalendarEnabled( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
}
void CalendarLocal::setReadOnly( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
}
void CalendarLocal::setAlarmEnabled( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
reInitAlarmSettings();
}
void CalendarLocal::setDefaultCalendarEnabledOnly()
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar);
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar);
}
diff --git a/libkcal/calendarlocal.h b/libkcal/calendarlocal.h
index eb7bf34..b70f0c9 100644
--- a/libkcal/calendarlocal.h
+++ b/libkcal/calendarlocal.h
@@ -1,232 +1,233 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brown
Copyright (c) 2001,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 KCAL_CALENDARLOCAL_H
#define KCAL_CALENDARLOCAL_H
#include "calendar.h"
namespace KCal {
class CalFormat;
/**
This class provides a calendar stored as a local file.
*/
class CalendarLocal : public Calendar
{
public:
/**
Constructs a new calendar, with variables initialized to sane values.
*/
CalendarLocal();
/**
Constructs a new calendar, with variables initialized to sane values.
*/
CalendarLocal( const QString &timeZoneId );
~CalendarLocal();
void addCalendar( Calendar* );
bool addCalendarFile( QString name, int id );
bool mergeCalendarFile( QString name );
bool mergeCalendar( Calendar* cal );
Incidence* incidenceForUid( const QString& uid, bool doNotCheckDuplicates );
void setSyncEventsReadOnly();
void setSyncEventsEnabled();
void stopAllTodos();
/**
Loads a calendar on disk in vCalendar or iCalendar format into the current
calendar. Any information already present is lost.
@return true, if successfull, false on error.
@param fileName the name of the calendar on disk.
*/
bool load( const QString &fileName );
/**
Writes out the calendar to disk in the specified \a format.
CalendarLocal takes ownership of the CalFormat object.
@return true, if successfull, false on error.
@param fileName the name of the file
*/
bool save( const QString &fileName, CalFormat *format = 0 );
/**
Clears out the current calendar, freeing all used memory etc. etc.
*/
void close();
void save() {}
/**
Add Event to calendar.
*/
void removeSyncInfo( QString syncProfile);
bool addAnniversaryNoDup( Event *event );
bool addEventNoDup( Event *event );
bool addEvent( Event *event );
/**
Deletes an event from this calendar.
*/
void deleteEvent( Event *event );
/**
Retrieves an event on the basis of the unique string ID.
*/
Event *event( const QString &uid );
/**
Return unfiltered list of all events in calendar.
*/
QPtrList<Event> rawEvents();
QPtrList<Event> getExternLastSyncEvents();
/**
Add a todo to the todolist.
*/
bool addTodo( Todo *todo );
bool addTodoNoDup( Todo *todo );
/**
Remove a todo from the todolist.
*/
void deleteTodo( Todo * );
/**
Searches todolist for an event with this unique string identifier,
returns a pointer or null.
*/
Todo *todo( const QString &uid );
/**
Return list of all todos.
*/
QPtrList<Todo> rawTodos();
/**
Returns list of todos due on the specified date.
*/
QPtrList<Todo> todos( const QDate &date );
/**
Return list of all todos.
Workaround because compiler does not recognize function of base class.
*/
QPtrList<Todo> todos() { return Calendar::todos(); }
/**
Add a Journal entry to calendar.
*/
bool addJournal( Journal * );
/**
Remove a Journal from the calendar.
*/
void deleteJournal( Journal * );
/**
Return Journal for given date.
*/
Journal *journal( const QDate & );
QPtrList<Journal> journals4Date( const QDate & );
/**
Return Journal with given UID.
*/
Journal *journal( const QString &uid );
/**
Return list of all Journals stored in calendar.
*/
QPtrList<Journal> journals();
/**
Return all alarms, which ocur in the given time interval.
*/
Alarm::List alarms( const QDateTime &from, const QDateTime &to );
/**
Return all alarms, which ocur before given date.
*/
Alarm::List alarmsTo( const QDateTime &to );
QDateTime nextAlarm( int daysTo ) ;
QDateTime nextAlarmEventDateTime() const;
void checkAlarmForIncidence( Incidence *, bool deleted ) ;
void registerAlarm();
void deRegisterAlarm();
QString getAlarmNotification();
QString nextSummary() const ;
/**
This method should be called whenever a Event is modified directly
via it's pointer. It makes sure that the calendar is internally
consistent.
*/
void update( IncidenceBase *incidence );
/**
Builds and then returns a list of all events that match for the
date specified. useful for dayView, etc. etc.
*/
QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false );
/**
Get unfiltered events for date \a qdt.
*/
QPtrList<Event> rawEventsForDate( const QDateTime &qdt );
/**
Get unfiltered events in a range of dates. If inclusive is set to true,
only events are returned, which are completely included in the range.
*/
QPtrList<Event> rawEvents( const QDate &start, const QDate &end,
bool inclusive = false );
Todo *todo( QString, QString );
Event *event( QString, QString );
void getIncidenceCount( int calId, int& events, int & todos, int & journals);
public slots:
void setCalendarEnabled( int id, bool enable );
void setAlarmEnabled( int id, bool enable );
void setReadOnly( int id, bool enable );
void setDefaultCalendarEnabledOnly();
void setCalendarRemove( int id );
+ void setAllCalendarEnabled( bool enable );
protected:
// Event* mNextAlarmEvent;
QString mNextSummary;
QString mNextAlarmEventDateTimeString;
QString mLastAlarmNotificationString;
QDateTime mNextAlarmEventDateTime;
QDateTime mNextAlarmDateTime;
void reInitAlarmSettings();
/** Notification function of IncidenceBase::Observer. */
void incidenceUpdated( IncidenceBase *i ) { update( i ); }
/** inserts an event into its "proper place" in the calendar. */
void insertEvent( Event *event );
/** Append alarms of incidence in interval to list of alarms. */
void appendAlarms( Alarm::List &alarms, Incidence *incidence,
const QDateTime &from, const QDateTime &to );
/** Append alarms of recurring events in interval to list of alarms. */
void appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence,
const QDateTime &from, const QDateTime &to );
private:
void init();
QPtrList<Event> mEventList;
QPtrList<Todo> mTodoList;
QPtrList<Journal> mJournalList;
};
}
#endif
diff --git a/libkdepim/ksyncmanager.cpp b/libkdepim/ksyncmanager.cpp
index 795cd30..d2cb71b 100644
--- a/libkdepim/ksyncmanager.cpp
+++ b/libkdepim/ksyncmanager.cpp
@@ -631,1043 +631,1042 @@ int KSyncManager::ringSync()
syncKDE();
#else
syncSharp();
#endif
} else {
if ( temp->getIsLocalFileSync() ) {
switch(mTargetApp)
{
case (KAPI):
if ( syncWithFile( temp->getRemoteFileNameAB( ), false ) )
mPrefs->mLastSyncedLocalFile = temp->getRemoteFileNameAB();
break;
case (KOPI):
if ( syncWithFile( temp->getRemoteFileName( ), false ) )
mPrefs->mLastSyncedLocalFile = temp->getRemoteFileName();
break;
case (PWMPI):
if ( syncWithFile( temp->getRemoteFileNamePWM( ), false ) )
mPrefs->mLastSyncedLocalFile = temp->getRemoteFileNamePWM();
break;
default:
qDebug("KSM: invalid apptype selected");
break;
}
} else {
if ( temp->getIsPhoneSync() ) {
mPhoneDevice = temp->getPhoneDevice( ) ;
mPhoneConnection = temp->getPhoneConnection( );
mPhoneModel = temp->getPhoneModel( );
syncPhone();
} else if ( temp->getIsPiSync() || temp->getIsPiSyncSpec()) {
mSpecificResources.clear();
if ( mTargetApp == KAPI ) {
mPassWordPiSync = temp->getRemotePwAB();
mActiveSyncPort = temp->getRemotePortAB();
mActiveSyncIP = temp->getRemoteIPAB();
} else if ( mTargetApp == KOPI ) {
mSpecificResources = QStringList::split( ":", temp->getResSpecKopi(),true );
mPassWordPiSync = temp->getRemotePw();
mActiveSyncPort = temp->getRemotePort();
mActiveSyncIP = temp->getRemoteIP();
} else {
mPassWordPiSync = temp->getRemotePwPWM();
mActiveSyncPort = temp->getRemotePortPWM();
mActiveSyncIP = temp->getRemoteIPPWM();
}
syncPi();
while ( !mPisyncFinished ) {
//qDebug("waiting ");
qApp->processEvents();
}
timer.start();
while ( timer.elapsed () < 2000 ) {
qApp->processEvents();
}
} else
syncRemote( temp, false );
}
}
timer.start();
mParent->topLevelWidget()->setCaption(i18n("Multiple sync in progress ... please wait!") );
while ( timer.elapsed () < 2000 ) {
qApp->processEvents();
#ifndef _WIN32_
sleep (1);
#endif
}
}
}
delete temp;
return syncedProfiles;
}
void KSyncManager::syncRemote( KSyncProfile* prof, bool ask)
{
QString question;
if ( ask ) {
question = i18n("Do you really want\nto remote sync\nwith profile \n")+ prof->getName()+" ?\n";
if ( QMessageBox::information( mParent, i18n("Sync"),
question,
i18n("Yes"), i18n("No"),
0, 0 ) != 0 )
return;
}
QString preCommand;
QString localTempFile;
QString postCommand;
switch(mTargetApp)
{
case (KAPI):
preCommand = prof->getPreSyncCommandAB();
postCommand = prof->getPostSyncCommandAB();
localTempFile = prof->getLocalTempFileAB();
break;
case (KOPI):
preCommand = prof->getPreSyncCommand();
postCommand = prof->getPostSyncCommand();
localTempFile = prof->getLocalTempFile();
break;
case (PWMPI):
preCommand = prof->getPreSyncCommandPWM();
postCommand = prof->getPostSyncCommandPWM();
localTempFile = prof->getLocalTempFilePWM();
break;
default:
qDebug("KSM::syncRemote: invalid apptype selected");
break;
}
int fi;
if ( (fi = preCommand.find("$PWD$")) > 0 ) {
QString pwd = getPassword();
preCommand = preCommand.left( fi )+ pwd + preCommand.mid( fi+5 );
}
int maxlen = 30;
if ( QApplication::desktop()->width() > 320 )
maxlen += 25;
mParent->topLevelWidget()->setCaption ( i18n( "Copy remote file to local machine..." ) );
int fileSize = 0;
int result = system ( preCommand );
// 0 : okay
// 256: no such file or dir
//
qDebug("KSM::Sync: Remote copy result(0 = okay): %d ",result );
if ( result != 0 ) {
unsigned int len = maxlen;
while ( len < preCommand.length() ) {
preCommand.insert( len , "\n" );
len += maxlen +2;
}
question = i18n("Sorry, the copy command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n").arg (preCommand) ;
QMessageBox::information( mParent, i18n("Sync - ERROR"),
question,
i18n("Okay!")) ;
mParent->topLevelWidget()->setCaption ("KDE-Pim");
return;
}
mParent->topLevelWidget()->setCaption ( i18n( "Copying succeed." ) );
//qDebug(" file **%s** ",prof->getLocalTempFile().latin1() );
if ( syncWithFile( localTempFile, true ) ) {
if ( mWriteBackFile ) {
int fi;
if ( (fi = postCommand.find("$PWD$")) > 0 ) {
QString pwd = getPassword();
postCommand = postCommand.left( fi )+ pwd + postCommand.mid( fi+5 );
}
mParent->topLevelWidget()->setCaption ( i18n( "Writing back file ..." ) );
result = system ( postCommand );
qDebug("KSM::Sync:Writing back file result: %d ", result);
if ( result != 0 ) {
mParent->topLevelWidget()->setCaption ( i18n( "Writing back file result: " )+QString::number( result ) );
return;
} else {
mParent->topLevelWidget()->setCaption ( i18n( "Syncronization sucessfully completed" ) );
}
}
}
return;
}
bool KSyncManager::edit_pisync_options()
{
QDialog dia( mParent, "dia", true );
dia.setCaption( i18n("Pi-Sync options for device: " ) +mCurrentSyncDevice );
QVBoxLayout lay ( &dia );
lay.setSpacing( 5 );
lay.setMargin( 3 );
QLabel lab1 ( i18n("Password for remote access:"), &dia);
lay.addWidget( &lab1 );
QLineEdit le1 (&dia );
lay.addWidget( &le1 );
QLabel lab2 ( i18n("Remote IP address:"), &dia);
lay.addWidget( &lab2 );
QLineEdit le2 (&dia );
lay.addWidget( &le2 );
QLabel lab3 ( i18n("Remote port number:\n(May be: 1 - 65535)"), &dia);
lay.addWidget( &lab3 );
QLineEdit le3 (&dia );
lay.addWidget( &le3 );
QPushButton pb ( "OK", &dia);
lay.addWidget( &pb );
connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) );
le1.setText( mPassWordPiSync );
le2.setText( mActiveSyncIP );
le3.setText( mActiveSyncPort );
if ( dia.exec() ) {
mPassWordPiSync = le1.text();
mActiveSyncPort = le3.text();
mActiveSyncIP = le2.text();
return true;
}
return false;
}
bool KSyncManager::edit_sync_options()
{
QDialog dia( mParent, "dia", true );
dia.setCaption( i18n("Device: " ) +mCurrentSyncDevice );
QButtonGroup gr ( 1, Qt::Horizontal, i18n("Sync preferences"), &dia);
QVBoxLayout lay ( &dia );
lay.setSpacing( 2 );
lay.setMargin( 3 );
lay.addWidget(&gr);
QRadioButton loc ( i18n("Take local entry on conflict"), &gr );
QRadioButton rem ( i18n("Take remote entry on conflict"), &gr );
QRadioButton newest( i18n("Take newest entry on conflict"), &gr );
QRadioButton ask( i18n("Ask for every entry on conflict"), &gr );
QRadioButton f_loc( i18n("Force: Take local entry always"), &gr );
QRadioButton f_rem( i18n("Force: Take remote entry always"), &gr );
//QRadioButton both( i18n("Take both on conflict"), &gr );
QPushButton pb ( "OK", &dia);
lay.addWidget( &pb );
connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) );
switch ( mSyncAlgoPrefs ) {
case 0:
loc.setChecked( true);
break;
case 1:
rem.setChecked( true );
break;
case 2:
newest.setChecked( true);
break;
case 3:
ask.setChecked( true);
break;
case 4:
f_loc.setChecked( true);
break;
case 5:
f_rem.setChecked( true);
break;
case 6:
// both.setChecked( true);
break;
default:
break;
}
if ( dia.exec() ) {
mSyncAlgoPrefs = rem.isChecked()*1+newest.isChecked()*2+ ask.isChecked()*3+ f_loc.isChecked()*4+ f_rem.isChecked()*5;//+ both.isChecked()*6 ;
return true;
}
return false;
}
QString KSyncManager::getPassword( )
{
QString retfile = "";
QDialog dia ( mParent, "input-dialog", true );
QLineEdit lab ( &dia );
lab.setEchoMode( QLineEdit::Password );
QVBoxLayout lay( &dia );
lay.setMargin(7);
lay.setSpacing(7);
lay.addWidget( &lab);
dia.setFixedSize( 230,50 );
dia.setCaption( i18n("Enter password") );
QPushButton pb ( "OK", &dia);
lay.addWidget( &pb );
connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) );
dia.show();
int res = dia.exec();
if ( res )
retfile = lab.text();
dia.hide();
qApp->processEvents();
return retfile;
}
void KSyncManager::confSync()
{
static KSyncPrefsDialog* sp = 0;
if ( ! sp ) {
sp = new KSyncPrefsDialog( mParent, "syncprefs", true );
}
sp->usrReadConfig();
#ifndef DESKTOP_VERSION
sp->showMaximized();
#else
sp->show();
#endif
sp->exec();
QStringList oldSyncProfileNames = mSyncProfileNames;
mSyncProfileNames = sp->getSyncProfileNames();
mLocalMachineName = sp->getLocalMachineName ();
int ii;
for ( ii = 0; ii < oldSyncProfileNames.count(); ++ii ) {
if ( ! mSyncProfileNames.contains( oldSyncProfileNames[ii] ) )
mImplementation->removeSyncInfo( oldSyncProfileNames[ii] );
}
QTimer::singleShot ( 1, this, SLOT ( fillSyncMenu() ) );
}
void KSyncManager::syncKDE()
{
mSyncWithDesktop = true;
emit save();
switch(mTargetApp)
{
case (KAPI):
{
#ifdef DESKTOP_VERSION
QString command = "kdeabdump33";
QString commandfile = "kdeabdump33";
QString commandpath = qApp->applicationDirPath () + "/";
#else
QString command = "kdeabdump33";
QString commandfile = "kdeabdump33";
QString commandpath = QDir::homeDirPath ()+"/";
#endif
if ( ! QFile::exists ( commandpath+commandfile ) )
command = commandfile;
else
command = commandpath+commandfile;
QString fileName = QDir::homeDirPath ()+"/.kdeaddressbookdump.vcf";
int result = system ( command.latin1());
qDebug("AB dump 33 command call result: %d ", result);
if ( result != 0 ) {
qDebug("Calling AB dump version 33 failed. Trying 34... ");
commandfile = "kdeabdump34";
if ( ! QFile::exists ( commandpath+commandfile ) )
command = commandfile;
else
command = commandpath+commandfile;
result = system ( command.latin1());
qDebug("AB dump 34 command call result: %d ", result);
if ( result != 0 ) {
KMessageBox::error( 0, i18n("Error accessing KDE addressbook data.\nMake sure the file\n%1kdeabdump3x\nexists ( x = 3 or 4 ).\nSupported KDE versions are 3.3 and 3.4.\nUsed version should be auto detected.\n").arg( commandpath ));
return;
}
}
if ( syncWithFile( fileName,true ) ) {
if ( mWriteBackFile ) {
command += " --read";
system ( command.latin1());
}
}
}
break;
case (KOPI):
{
#ifdef DESKTOP_VERSION
QString command = "kdecaldump33";
QString commandfile = "kdecaldump33";
QString commandpath = qApp->applicationDirPath () + "/";
#else
QString command = "kdecaldump33";
QString commandfile = "kdecaldump33";
QString commandpath = QDir::homeDirPath ()+"/";
#endif
if ( ! QFile::exists ( commandpath+commandfile ) )
command = commandfile;
else
command = commandpath+commandfile;
QString fileName = QDir::homeDirPath ()+"/.kdecalendardump.ics";
int result = system ( command.latin1());
qDebug("Cal dump 33 command call result result: %d ", result);
if ( result != 0 ) {
qDebug("Calling CAL dump version 33 failed. Trying 34... ");
commandfile = "kdecaldump34";
if ( ! QFile::exists ( commandpath+commandfile ) )
command = commandfile;
else
command = commandpath+commandfile;
result = system ( command.latin1());
qDebug("Cal dump 34 command call result result: %d ", result);
if ( result != 0 ) {
KMessageBox::error( 0, i18n("Error accessing KDE calendar data.\nMake sure the file\n%1kdecaldump3x\nexists ( x = 3 or 4 ).\nSupported KDE versions are 3.3 and 3.4.\nUsed version should be auto detected.\n").arg( commandpath ));
return;
}
}
if ( syncWithFile( fileName,true ) ) {
if ( mWriteBackFile ) {
command += " --read";
system ( command.latin1());
}
}
}
break;
case (PWMPI):
break;
default:
qDebug("KSM::slotSyncMenu: invalid apptype selected");
break;
}
}
void KSyncManager::syncSharp()
{
if ( ! syncExternalApplication("sharp") )
qDebug("KSM::ERROR sync sharp ");
}
bool KSyncManager::syncExternalApplication(QString resource)
{
emit save();
if ( mAskForPreferences )
if ( !edit_sync_options()) {
mParent->topLevelWidget()->setCaption( i18n("Syncing aborted. Nothing synced.") );
return false;
}
qDebug("KSM::Sync extern %s", resource.latin1());
bool syncOK = mImplementation->syncExternal(this, resource);
return syncOK;
}
void KSyncManager::syncPhone()
{
syncExternalApplication("phone");
}
void KSyncManager::showProgressBar(int percentage, QString caption, int total)
{
if (!bar->isVisible())
{
int w = 300;
if ( QApplication::desktop()->width() < 320 )
w = 220;
int h = bar->sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
bar->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
bar->setCaption (caption);
bar->setTotalSteps ( total ) ;
bar->show();
}
bar->raise();
bar->setProgress( percentage );
qApp->processEvents();
}
void KSyncManager::hideProgressBar()
{
bar->hide();
qApp->processEvents();
}
bool KSyncManager::isProgressBarCanceled()
{
return !bar->isVisible();
}
QString KSyncManager::syncFileName()
{
QString fn = "tempfile";
switch(mTargetApp)
{
case (KAPI):
fn = "tempsyncab.vcf";
break;
case (KOPI):
fn = "tempsynccal.ics";
break;
case (PWMPI):
fn = "tempsyncpw.pwm";
break;
default:
break;
}
#ifdef DESKTOP_VERSION
return locateLocal( "tmp", fn );
#else
return (QString( "/tmp/" )+ fn );
#endif
}
void KSyncManager::syncPi()
{
mIsKapiFile = true;
mPisyncFinished = false;
qApp->processEvents();
if ( mAskForPreferences )
if ( !edit_pisync_options()) {
mParent->topLevelWidget()->setCaption( i18n("Syncing aborted. Nothing synced.") );
mPisyncFinished = true;
return;
}
bool ok;
Q_UINT16 port = mActiveSyncPort.toUInt(&ok);
if ( ! ok ) {
mParent->topLevelWidget()->setCaption( i18n("Sorry, no valid port.Syncing cancelled.") );
mPisyncFinished = true;
return;
}
mCurrentResourceLocal = "";
mCurrentResourceRemote = "";
- qDebug ( "KSM: sync pi %d",mSpecificResources.count() );
if ( mSpecificResources.count() ) {
int lastSyncRes = mSpecificResources.count()/2;
int ccc = mSpecificResources.count()-1;
while ( lastSyncRes > 0 && ccc > 0 && mSpecificResources[ ccc ].isEmpty() ) {
--ccc;
--lastSyncRes;
- qDebug ( "KSM: sync pi %d",ccc );
+ //qDebug ( "KSM: sync pi %d",ccc );
}
int startLocal = 0;
int startRemote = mSpecificResources.count()/2;
emit multiResourceSyncStart( true );
while ( startLocal < mSpecificResources.count()/2 ) {
if ( startLocal+1 >= lastSyncRes )
emit multiResourceSyncStart( false );
mPisyncFinished = false;
mCurrentResourceLocal = mSpecificResources[ startLocal ];
mCurrentResourceRemote = mSpecificResources[ startRemote ];
- qDebug ( "KSM: AAASyncing resources: Local: %s --- Remote: %s ",mCurrentResourceLocal.latin1(), mCurrentResourceRemote.latin1() );
+ //qDebug ( "KSM: AAASyncing resources: Local: %s --- Remote: %s ",mCurrentResourceLocal.latin1(), mCurrentResourceRemote.latin1() );
if ( !mCurrentResourceRemote.isEmpty() ) {
qDebug ( "KSM: Syncing resources: Local: %s --- Remote: %s ",mCurrentResourceLocal.latin1(), mCurrentResourceRemote.latin1() );
KCommandSocket* commandSocket = new KCommandSocket( mCurrentResourceRemote, mPassWordPiSync, port, mActiveSyncIP, this, mParent->topLevelWidget() );
connect( commandSocket, SIGNAL(commandFinished( KCommandSocket*, int )), this, SLOT(deleteCommandSocket(KCommandSocket*, int)) );
commandSocket->readFile( syncFileName() );
while ( !mPisyncFinished ) {
//qDebug("waiting ");
qApp->processEvents();
}
}
++startRemote;
++startLocal;
}
mPisyncFinished = true;
} else {
KCommandSocket* commandSocket = new KCommandSocket( "", mPassWordPiSync, port, mActiveSyncIP, this, mParent->topLevelWidget() );
connect( commandSocket, SIGNAL(commandFinished( KCommandSocket*, int )), this, SLOT(deleteCommandSocket(KCommandSocket*, int)) );
commandSocket->readFile( syncFileName() );
}
}
void KSyncManager::deleteCommandSocket(KCommandSocket*s, int state)
{
//enum { success, errorW, errorR, quiet };
if ( state == KCommandSocket::errorR ||state == KCommandSocket::errorTO ||state == KCommandSocket::errorPW ||
state == KCommandSocket::errorCA ||state == KCommandSocket::errorFI ||state == KCommandSocket::errorUN||state == KCommandSocket::errorED ) {
if ( state == KCommandSocket::errorPW )
mParent->topLevelWidget()->setCaption( i18n("Wrong password: Receiving remote file failed.") );
else if ( state == KCommandSocket::errorR ||state == KCommandSocket::errorTO )
mParent->topLevelWidget()->setCaption( i18n("ERROR: Receiving remote file failed.") );
else if ( state == KCommandSocket::errorCA )
mParent->topLevelWidget()->setCaption( i18n("Sync cancelled from remote.") );
else if ( state == KCommandSocket::errorFI )
mParent->topLevelWidget()->setCaption( i18n("File error on remote.") );
else if ( state == KCommandSocket::errorED )
mParent->topLevelWidget()->setCaption( i18n("Please close error dialog on remote.") );
else if ( state == KCommandSocket::errorUN )
mParent->topLevelWidget()->setCaption( i18n("Unknown error on remote.") );
delete s;
if ( state == KCommandSocket::errorR ) {
KCommandSocket* commandSocket = new KCommandSocket( "",mPassWordPiSync, mActiveSyncPort.toUInt(), mActiveSyncIP, this, mParent->topLevelWidget());
connect( commandSocket, SIGNAL(commandFinished( KCommandSocket*, int)), this, SLOT(deleteCommandSocket(KCommandSocket*, int )) );
commandSocket->sendStop();
}
mPisyncFinished = true;
return;
} else if ( state == KCommandSocket::errorW ) {
mParent->topLevelWidget()->setCaption( i18n("ERROR:Writing back file failed.") );
mPisyncFinished = true;
} else if ( state == KCommandSocket::successR ) {
QTimer::singleShot( 1, this , SLOT ( readFileFromSocket()));
} else if ( state == KCommandSocket::successW ) {
mParent->topLevelWidget()->setCaption( i18n("Pi-Sync successful!") );
mPisyncFinished = true;
} else if ( state == KCommandSocket::quiet ){
qDebug("KSS: quiet ");
mPisyncFinished = true;
} else {
qDebug("KSS: Error: unknown state: %d ", state);
mPisyncFinished = true;
}
delete s;
}
void KSyncManager::readFileFromSocket()
{
QString fileName = syncFileName();
bool syncOK = true;
mParent->topLevelWidget()->setCaption( i18n("Remote file saved to temp file.") );
if ( ! syncWithFile( fileName , true ) ) {
mParent->topLevelWidget()->setCaption( i18n("Syncing failed.") );
syncOK = false;
}
KCommandSocket* commandSocket = new KCommandSocket( mCurrentResourceRemote,mPassWordPiSync, mActiveSyncPort.toUInt(), mActiveSyncIP, this, mParent->topLevelWidget() );
connect( commandSocket, SIGNAL(commandFinished( KCommandSocket*, int)), this, SLOT(deleteCommandSocket(KCommandSocket*, int )) );
if ( mWriteBackFile && syncOK ) {
mParent->topLevelWidget()->setCaption( i18n("Sending back file ...") );
commandSocket->writeFile( fileName );
}
else {
commandSocket->sendStop();
if ( syncOK )
mParent->topLevelWidget()->setCaption( i18n("Pi-Sync succesful!") );
mPisyncFinished = true;
}
}
KServerSocket:: KServerSocket ( QString pw, Q_UINT16 port, int backlog, QObject * parent, const char * name ) : QServerSocket( port, backlog, parent, name )
{
mPassWord = pw;
mSocket = 0;
mSyncActionDialog = 0;
blockRC = false;
mErrorMessage = 0;
}
void KServerSocket::newConnection ( int socket )
{
// qDebug("KServerSocket:New connection %d ", socket);
if ( mSocket ) {
qDebug("KSS::newConnection Socket deleted! ");
delete mSocket;
mSocket = 0;
}
mSocket = new QSocket( this );
connect( mSocket , SIGNAL(readyRead()), this, SLOT(readClient()) );
connect( mSocket , SIGNAL(delayedCloseFinished()), this, SLOT(discardClient()) );
mSocket->setSocket( socket );
}
void KServerSocket::discardClient()
{
QTimer::singleShot( 10, this , SLOT ( deleteSocket()));
}
void KServerSocket::deleteSocket()
{
qDebug("KSS::deleteSocket");
if ( mSocket ) {
delete mSocket;
mSocket = 0;
}
if ( mErrorMessage )
QTimer::singleShot( 10, this , SLOT ( displayErrorMessage()));
}
void KServerSocket::readClient()
{
if ( blockRC )
return;
if ( mSocket == 0 ) {
qDebug("ERROR::KSS::readClient(): mSocket == 0 ");
return;
}
if ( mErrorMessage ) {
mErrorMessage = 999;
error_connect("ERROR_ED\r\n\r\n");
return;
}
mResource = "";
mErrorMessage = 0;
//qDebug("KServerSocket::readClient()");
if ( mSocket->canReadLine() ) {
QString line = mSocket->readLine();
//qDebug("KServerSocket readline: %s ", line.latin1());
QStringList tokens = QStringList::split( QRegExp("[ \r\n][ \r\n]*"), line );
if ( tokens[0] == "GET" ) {
if ( tokens[1] == mPassWord ) {
//emit sendFile( mSocket );
bool ok = false;
QDateTime dt = KGlobal::locale()->readDateTime( tokens[2], KLocale::ISODate, &ok);
if ( ok ) {
KSyncManager::mRequestedSyncEvent = dt;
}
else
KSyncManager::mRequestedSyncEvent = QDateTime();
mResource =tokens[3];
send_file();
}
else {
mErrorMessage = 1;
error_connect("ERROR_PW\r\n\r\n");
}
}
if ( tokens[0] == "PUT" ) {
if ( tokens[1] == mPassWord ) {
//emit getFile( mSocket );
blockRC = true;
mResource =tokens[2];
get_file();
}
else {
mErrorMessage = 2;
error_connect("ERROR_PW\r\n\r\n");
end_connect();
}
}
if ( tokens[0] == "STOP" ) {
//emit endConnect();
end_connect();
}
}
}
void KServerSocket::displayErrorMessage()
{
if ( mErrorMessage == 1 ) {
KMessageBox::error( 0, i18n("Got send file request\nwith invalid password"), i18n("Pi-Sync Error"));
mErrorMessage = 0;
}
else if ( mErrorMessage == 2 ) {
KMessageBox::error( 0, i18n("Got receive file request\nwith invalid password"), i18n("Pi-Sync Error"));
mErrorMessage = 0;
}
}
void KServerSocket::error_connect( QString errmess )
{
QTextStream os( mSocket );
os.setEncoding( QTextStream::Latin1 );
os << errmess ;
mSocket->close();
if ( mSocket->state() == QSocket::Idle ) {
QTimer::singleShot( 0, this , SLOT ( discardClient()));
}
}
void KServerSocket::end_connect()
{
delete mSyncActionDialog;
mSyncActionDialog = 0;
}
void KServerSocket::send_file()
{
//qDebug("MainWindow::sendFile(QSocket* s) ");
if ( mSyncActionDialog )
delete mSyncActionDialog;
mSyncActionDialog = new QDialog ( 0, "input-dialog", true );
mSyncActionDialog->setCaption(i18n("Received sync request"));
QLabel* label = new QLabel( i18n("Synchronizing from remote ...\n\nDo not use this application!\n\nIf syncing fails\nyou can close this dialog."), mSyncActionDialog );
label->setAlignment ( Qt::AlignHCenter );
QVBoxLayout* lay = new QVBoxLayout( mSyncActionDialog );
lay->addWidget( label);
lay->setMargin(7);
lay->setSpacing(7);
if ( KSyncManager::mRequestedSyncEvent.isValid() ) {
int secs = QDateTime::currentDateTime().secsTo( KSyncManager::mRequestedSyncEvent );
//secs = 333;
if ( secs < 0 )
secs = secs * (-1);
if ( secs > 30 )
//if ( true )
{
QString warning = i18n("Clock skew of\nsyncing devices\nis %1 seconds!").arg( secs );
QLabel* label = new QLabel( warning, mSyncActionDialog );
label->setAlignment ( Qt::AlignHCenter );
lay->addWidget( label);
if ( secs > 180 )
{
if ( secs > 300 ) {
if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel(0, i18n("The clocks of the syncing\ndevices have a difference\nof more than 5 minutes.\nPlease adjust your clocks.\nYou may get wrong syncing results!\nPlease confirm synchronization!"), i18n("High clock skew!"),i18n("Synchronize!"))) {
qDebug("KSS::Sync cancelled ,cs");
mErrorMessage = 0;
end_connect();
error_connect("ERROR_CA\r\n\r\n");
return ;
}
}
QFont f = label->font();
f.setPointSize ( f.pointSize() *2 );
f. setBold (true );
QLabel* label = new QLabel( warning, mSyncActionDialog );
label->setFont( f );
warning = i18n("ADJUST\nYOUR\nCLOCKS!");
label->setText( warning );
label->setAlignment ( Qt::AlignHCenter );
lay->addWidget( label);
mSyncActionDialog->setFixedSize( 230, 300);
} else {
mSyncActionDialog->setFixedSize( 230, 200);
}
} else {
mSyncActionDialog->setFixedSize( 230, 120);
}
} else
mSyncActionDialog->setFixedSize( 230, 120);
mSyncActionDialog->show();
mSyncActionDialog->raise();
emit request_file(mResource);
emit request_file();
qApp->processEvents();
QString fileName = mFileName;
QFile file( fileName );
if (!file.open( IO_ReadOnly ) ) {
mErrorMessage = 0;
end_connect();
error_connect("ERROR_FI\r\n\r\n");
return ;
}
mSyncActionDialog->setCaption( i18n("Sending file...") );
QTextStream ts( &file );
ts.setEncoding( QTextStream::Latin1 );
QTextStream os( mSocket );
os.setEncoding( QTextStream::Latin1 );
while ( ! ts.atEnd() ) {
os << ts.readLine() << "\r\n";
}
os << "\r\n";
//os << ts.read();
file.close();
mSyncActionDialog->setCaption( i18n("Waiting for synced file...") );
mSocket->close();
if ( mSocket->state() == QSocket::Idle )
QTimer::singleShot( 10, this , SLOT ( discardClient()));
}
void KServerSocket::get_file()
{
mSyncActionDialog->setCaption( i18n("Receiving synced file...") );
piTime.start();
piFileString = "";
QTimer::singleShot( 1, this , SLOT (readBackFileFromSocket( ) ));
}
void KServerSocket::readBackFileFromSocket()
{
//qDebug("readBackFileFromSocket() %d ", piTime.elapsed ());
while ( mSocket->canReadLine () ) {
piTime.restart();
QString line = mSocket->readLine ();
piFileString += line;
//qDebug("readline: %s ", line.latin1());
mSyncActionDialog->setCaption( i18n("Received %1 bytes").arg( piFileString.length() ) );
}
if ( piTime.elapsed () < 3000 ) {
// wait for more
//qDebug("waitformore ");
QTimer::singleShot( 100, this , SLOT (readBackFileFromSocket( ) ));
return;
}
QString fileName = mFileName;
QFile file ( fileName );
if (!file.open( IO_WriteOnly ) ) {
delete mSyncActionDialog;
mSyncActionDialog = 0;
qDebug("KSS:Error open read back file ");
piFileString = "";
emit file_received( false, mResource);
emit file_received( false);
blockRC = false;
return ;
}
// mView->setLoadedFileVersion(QDateTime::currentDateTime().addSecs( -1));
QTextStream ts ( &file );
ts.setEncoding( QTextStream::Latin1 );
mSyncActionDialog->setCaption( i18n("Writing file to disk...") );
ts << piFileString;
mSocket->close();
if ( mSocket->state() == QSocket::Idle )
QTimer::singleShot( 10, this , SLOT ( discardClient()));
file.close();
piFileString = "";
emit file_received( true, mResource );
emit file_received( true);
delete mSyncActionDialog;
mSyncActionDialog = 0;
blockRC = false;
}
KCommandSocket::KCommandSocket ( QString remres, QString password, Q_UINT16 port, QString host, QObject * parent, QWidget * cap, const char * name ): QObject( parent, name )
{
mRemoteResource = remres;
if ( mRemoteResource.isEmpty() )
mRemoteResource = "ALL";
else
mRemoteResource.replace (QRegExp (" "),"_" );
mPassWord = password;
mSocket = 0;
mFirst = false;
mFirstLine = true;
mPort = port;
mHost = host;
tlw = cap;
mRetVal = quiet;
mTimerSocket = new QTimer ( this );
connect( mTimerSocket, SIGNAL ( timeout () ), this, SLOT ( updateConnectDialog() ) );
mConnectProgress.setCaption( i18n("Pi-Sync") );
connect( &mConnectProgress, SIGNAL ( cancelled () ), this, SLOT ( deleteSocket() ) );
mConnectCount = -1;
}
void KCommandSocket::sendFileRequest()
{
if ( tlw )
tlw->setCaption( i18n("Connected! Sending request for remote file ...") );
mConnectProgress.hide();
mConnectCount = 300;mConnectMax = 300;
mConnectProgress.setCaption( i18n("Pi-Sync: Connected!") );
mTimerSocket->start( 100, true );
QTextStream os( mSocket );
os.setEncoding( QTextStream::Latin1 );
QString curDt = " " +KGlobal::locale()->formatDateTime(QDateTime::currentDateTime().addSecs(-1),true, true,KLocale::ISODate );
os << "GET " << mPassWord << curDt << " " << mRemoteResource << "\r\n\r\n";
}
void KCommandSocket::readFile( QString fn )
{
if ( !mSocket ) {
mSocket = new QSocket( this );
connect( mSocket, SIGNAL(readyRead()), this, SLOT(startReadFileFromSocket()) );
connect( mSocket, SIGNAL(delayedCloseFinished ()), this, SLOT(deleteSocket()) );
connect( mSocket, SIGNAL(connected ()), this, SLOT(sendFileRequest() ));
}
mFileString = "";
mFileName = fn;
mFirst = true;
if ( tlw )
tlw->setCaption( i18n("Trying to connect to remote...") );
mConnectCount = 30;mConnectMax = 30;
mTimerSocket->start( 1000, true );
mSocket->connectToHost( mHost, mPort );
qDebug("KSS: Waiting for connection");
}
void KCommandSocket::updateConnectDialog()
{
if ( mConnectCount == mConnectMax ) {
//qDebug("MAXX %d", mConnectMax);
mConnectProgress.setTotalSteps ( 30 );
mConnectProgress.show();
mConnectProgress.setLabelText( i18n("Trying to connect to remote...") );
}
//qDebug("updateConnectDialog() %d", mConnectCount);
mConnectProgress.raise();
mConnectProgress.setProgress( (mConnectMax - mConnectCount)%30 );
--mConnectCount;
if ( mConnectCount > 0 )
mTimerSocket->start( 1000, true );
else
deleteSocket();
}
void KCommandSocket::writeFile( QString fileName )
{
if ( !mSocket ) {
mSocket = new QSocket( this );
connect( mSocket, SIGNAL(delayedCloseFinished ()), this, SLOT(deleteSocket()) );
connect( mSocket, SIGNAL(connected ()), this, SLOT(writeFileToSocket()) );
}
mFileName = fileName ;
mConnectCount = 30;mConnectMax = 30;
mTimerSocket->start( 1000, true );
mSocket->connectToHost( mHost, mPort );
}
void KCommandSocket::writeFileToSocket()
{
mTimerSocket->stop();
QFile file2( mFileName );
if (!file2.open( IO_ReadOnly ) ) {
mConnectProgress.hide();
mConnectCount = -1;
mRetVal= errorW;
mSocket->close();
if ( mSocket->state() == QSocket::Idle )
QTimer::singleShot( 10, this , SLOT ( deleteSocket()));
return ;
}
mConnectProgress.setTotalSteps ( file2.size() );
mConnectProgress.show();
int count = 0;
mConnectProgress.setLabelText( i18n("Sending back synced file...") );
mConnectProgress.setProgress( count );
mConnectProgress.blockSignals( true );
QTextStream ts2( &file2 );
ts2.setEncoding( QTextStream::Latin1 );
QTextStream os2( mSocket );
os2.setEncoding( QTextStream::Latin1 );
os2 << "PUT " << mPassWord << " " << mRemoteResource << "\r\n\r\n";;
int byteCount = 0;
int byteMax = file2.size()/53;
while ( ! ts2.atEnd() ) {
qApp->processEvents();
if ( byteCount > byteMax ) {
byteCount = 0;
mConnectProgress.setProgress( count );
}
QString temp = ts2.readLine();
count += temp.length();
byteCount += temp.length();
os2 << temp << "\r\n";
}
file2.close();
mConnectProgress.hide();
mConnectCount = -1;
os2 << "\r\n";
mRetVal= successW;
mSocket->close();
if ( mSocket->state() == QSocket::Idle )
QTimer::singleShot( 10, this , SLOT ( deleteSocket()));
mConnectProgress.blockSignals( false );
}
void KCommandSocket::sendStop()
{
if ( !mSocket ) {
mSocket = new QSocket( this );
connect( mSocket, SIGNAL(delayedCloseFinished ()), this, SLOT(deleteSocket()) );
}
mSocket->connectToHost( mHost, mPort );
QTextStream os2( mSocket );
os2.setEncoding( QTextStream::Latin1 );
os2 << "STOP\r\n\r\n";
mSocket->close();
if ( mSocket->state() == QSocket::Idle )
QTimer::singleShot( 10, this , SLOT ( deleteSocket()));
}
void KCommandSocket::startReadFileFromSocket()
{
if ( ! mFirst )
return;
mConnectProgress.setLabelText( i18n("Receiving file from remote...") );
mFirst = false;
mFileString = "";
mTime.start();