-rw-r--r-- | korganizer/calendarview.cpp | 5 | ||||
-rw-r--r-- | libkcal/sharpformat.cpp | 2 |
2 files changed, 5 insertions, 2 deletions
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp index 5150455..f859b90 100644 --- a/korganizer/calendarview.cpp +++ b/korganizer/calendarview.cpp @@ -506,785 +506,788 @@ void CalendarView::computeAlarm( QString 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 ¬i ) { //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 ); } void CalendarView::addAlarm(const QDateTime &qdt, const QString ¬i ) { //qDebug("+++++addAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { #ifndef DESKTOP_VERSION AlarmServer::addAlarm ( qdt,"koalarm", noti.latin1() ); #endif return; } 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 ); } void CalendarView::removeAlarm(const QDateTime &qdt, const QString ¬i ) { //qDebug("-----removeAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { #ifndef DESKTOP_VERSION AlarmServer::deleteAlarm (qdt ,"koalarm" ,noti.latin1() ); #endif return; } mAlarmTimer->stop(); } void CalendarView::selectWeekNum ( int num ) { dateNavigator()->selectWeek( num ); 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 } void CalendarView::confSync() { static KSyncPrefsDialog* sp = 0; if ( ! sp ) { sp = new KSyncPrefsDialog( this, "syncprefs", true ); } sp->usrReadConfig(); #ifndef DESKTOP_VERSION sp->showMaximized(); #else sp->show(); #endif sp->exec(); KOPrefs::instance()->mSyncProfileNames = sp->getSyncProfileNames(); KOPrefs::instance()->mLocalMachineName = sp->getLocalMachineName (); } //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 ) { //void setZaurusId(int id); // int zaurusId() const; // void setZaurusUid(int id); // int zaurusUid() const; // void setZaurusStat(int id); // int zaurusStat() const; // 0 equal // 1 take local // 2 take remote // 3 cancel QDateTime lastSync = mLastCalendarSync; if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) { bool remCh, locCh; remCh = ( remote->getCsum(mCurrentSyncDevice) != local->getCsum(mCurrentSyncDevice) ); locCh = ( local->lastModified() > mLastCalendarSync ); //qDebug("locCh %d remCh %d locuid %d remuid %d", locCh, remCh,local->zaurusUid(), remote->zaurusUid() ); if ( !remCh && ! locCh ) { //qDebug("both not changed "); lastSync = local->lastModified().addDays(1); } else { if ( locCh ) { //qDebug("loc changed %d %d", local->zaurusStat(), local->revision() ); lastSync = local->lastModified().addDays( -1 ); if ( !remCh ) remote->setLastModified( lastSync.addDays( -1 ) ); } else { //qDebug(" not loc changed "); lastSync = local->lastModified().addDays( 1 ); if ( remCh ) remote->setLastModified( lastSync.addDays( 1 ) ); } } full = true; if ( mode < SYNC_PREF_ASK ) mode = SYNC_PREF_ASK; } else { if ( local->lastModified() == remote->lastModified() ) 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", local->lastModified().toString().latin1() , local->revision(), remote->lastModified().toString().latin1(), remote->revision()); //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() ); //full = true; //debug only if ( full ) { bool equ = false; if ( local->type() == "Event" ) { equ = (*((Event*) local) == *((Event*) remote)); } else if ( local->type() =="Todo" ) equ = (*((Todo*) local) == (*(Todo*) remote)); else if ( local->type() =="Journal" ) 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; if ( full && mode < SYNC_PREF_NEWEST ) mode = SYNC_PREF_ASK; switch( mode ) { case SYNC_PREF_LOCAL: if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; return 1; break; case SYNC_PREF_REMOTE: if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; return 2; break; case SYNC_PREF_NEWEST: if ( local->lastModified() > remote->lastModified() ) return 1; else return 2; break; case SYNC_PREF_ASK: //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); localIsNew = local->lastModified() > remote->lastModified(); 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 ( KOPrefs::instance()->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 ); mCalendar->addEvent( lse ); } return lse; } // probaly useless void CalendarView::setupExternSyncProfiles() { Event* lse; mExternLastSyncEvent.clear(); int i; for ( i = 0; i < KOPrefs::instance()->mExternSyncProfiles.count(); ++i ) { lse = mCalendar->event( "last-syncEvent-"+ KOPrefs::instance()->mExternSyncProfiles[i] ); if ( lse ) mExternLastSyncEvent.append( lse ); else qDebug("Last Sync event not found for %s ", KOPrefs::instance()->mExternSyncProfiles[i].latin1()); } } // 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 ) + if ( lastSync.count() == 0 ) { + //qDebug(" lastSync.count() == 0"); return; + } if ( toDelete->type() == "Journal" ) 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->type() == "Todo" ) 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; //QPtrList<Event> el = local->rawEvents(); Event* eventR; QString uid; int take; Event* eventL; Event* eventRSync; Event* eventLSync; QPtrList<Event> eventRSyncSharp = remote->getExternLastSyncEvents(); QPtrList<Event> eventLSyncSharp = local->getExternLastSyncEvents(); bool fullDateRange = false; mLastCalendarSync = QDateTime::currentDateTime(); QDateTime modifiedCalendar = mLastCalendarSync;; eventR = remote->event("last-syncEvent-"+mCurrentSyncName ); if ( eventR ) { eventRSync = (Event*) eventR->clone(); remote->deleteEvent(eventR ); } 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") ); } eventLSync = getLastSyncEvent(); 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("%d %d %d %d ", eventLSync->dtStart().time().second(), eventLSync->dtStart().time().msec() , eventRSync->dtStart().time().second(), eventRSync->dtStart().time().msec()); fullDateRange = true; } } 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("mLastCalendarSync %s ",mLastCalendarSync.toString().latin1() ); QPtrList<Incidence> er = remote->rawIncidences(); Incidence* inR = er.first(); Incidence* inL; QProgressBar bar( er.count(),0 ); bar.setCaption (i18n("Syncing - close to abort!") ); 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; qApp->processEvents(); if ( !skipIncidence ) { inL = local->incidence( uid ); if ( inL ) { // maybe conflict - same uid in both calendars int maxrev = inL->revision(); if ( maxrev < inR->revision() ) maxrev = inR->revision(); 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 inL->setCsum( mCurrentSyncDevice, inR->getCsum(mCurrentSyncDevice) ); remote->deleteIncidence( inR ); if ( inL->revision() < maxrev ) inL->setRevision( maxrev ); remote->addIncidence( inL->clone() ); ++changedRemote; } else { if ( inR->revision() < maxrev ) inR->setRevision( maxrev ); local->deleteIncidence( inL ); local->addIncidence( inR->clone() ); ++changedLocal; } } } else { // no conflict if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) { QString des = eventLSync->description(); QString pref = "e"; if ( inR->type() == "Todo" ) 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 ); local->addIncidence( inR->clone() ); ++addedEvent; } } else { if ( inR->lastModified() > mLastCalendarSync || mode == 5 ) { inR->setLastModified( modifiedCalendar ); local->addIncidence( inR->clone() ); ++addedEvent; } else { checkExternSyncEvent(eventRSyncSharp, inR); remote->deleteIncidence( inR ); ++deletedEventR; } } } } 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->type() == "Journal" ) skipIncidence = true; if ( !skipIncidence ) { inR = remote->incidence( uid ); if ( ! inR ) { if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) { if ( !inL->getID(mCurrentSyncDevice).isEmpty() && mode != 4 ) { local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { inL->removeID(mCurrentSyncDevice ); ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } else { if ( inL->lastModified() < mLastCalendarSync && mode != 4 ) { checkExternSyncEvent(eventLSyncSharp, inL); local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } } } inL = el.next(); } bar.hide(); mLastCalendarSync = QDateTime::currentDateTime().addSecs( 1 ); 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 ); if ( mGlobalSyncMode == SYNC_MODE_NORMAL) remote->addEvent( eventRSync ); 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"),addedEvent, addedEventR, changedLocal, changedRemote, deletedEventL, deletedEventR ); if ( KOPrefs::instance()->mShowSyncSummary ) { KMessageBox::information(this, mes, i18n("KO/Pi Synchronization") ); } qDebug( mes ); mCalendar->checkAlarmForIncidence( 0, true ); return syncOK; } void CalendarView::setSyncDevice( QString s ) { mCurrentSyncDevice= s; } void CalendarView::setSyncName( QString s ) { mCurrentSyncName= s; } bool CalendarView::syncCalendar(QString filename, int mode) { mGlobalSyncMode = SYNC_MODE_NORMAL; CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); FileStorage* storage = new FileStorage( calendar ); bool syncOK = false; storage->setFileName( filename ); // qDebug("loading ... "); if ( storage->load(KOPrefs::instance()->mUseQuicksave) ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, mode ); getEventViewerDialog()->setSyncMode( false ); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { storage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); storage->save(); } } setModified( true ); } delete storage; delete calendar; if ( syncOK ) updateView(); return syncOK; } void CalendarView::syncSharp() { #ifndef DESKTOP_VERSION mGlobalSyncMode = SYNC_MODE_EXTERNAL; //mCurrentSyncDevice = "sharp-DTM"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; SharpFormat sharpFormat; if ( sharpFormat.load( calendar, mCalendar ) ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { QPtrList<Incidence> iL = mCalendar->rawIncidences(); Incidence* inc = iL.first(); /* obsolete while ( inc ) { inc->setZaurusStat( inc->revision () ); inc = iL.next(); } */ // pending: clean last sync event description sharpFormat.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 ); } } } 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(); return ;//syncOK; #endif } #include <kabc/stdaddressbook.h> bool CalendarView::importBday() { 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; } } updateView(); topLevelWidget()->setCaption(QString::number( addCount )+ i18n(" birthdays/anniversaries added!")); return true; } bool CalendarView::addAnniversary( QDate date, QString name, KCal::Attendee* a, bool birthday) { //qDebug("addAnni "); Event * ev = new Event(); if ( a ) { ev->addAttendee( a ); } diff --git a/libkcal/sharpformat.cpp b/libkcal/sharpformat.cpp index ebfe164..4e54fdf 100644 --- a/libkcal/sharpformat.cpp +++ b/libkcal/sharpformat.cpp @@ -1,745 +1,745 @@ /* This file is part of libkcal. Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qapplication.h> #include <qptrlist.h> #include <qregexp.h> #include <qmessagebox.h> #include <qclipboard.h> #include <qfile.h> #include <qtextstream.h> #include <qtextcodec.h> #include <qxml.h> #include <qlabel.h> #include <kdebug.h> #include <klocale.h> #include <kglobal.h> #include "calendar.h" #include "alarm.h" #include "recurrence.h" #include "calendarlocal.h" #include "sharpformat.h" #include "syncdefines.h" using namespace KCal; //CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //ARSD silentalarm = 0 // 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly // 12 RFRQ // 13 RPOS pos = 4. monday in month // 14 RDYS days: 1 mon/ 2 tue .. 64 sun // 15 REND 0 = no end/ 1 = end // 16 REDT rec end dt //ALSD //ALED //MDAY class SharpParser : public QObject { public: SharpParser( Calendar *calendar ) : mCalendar( calendar ) { oldCategories = 0; } bool startElement( Calendar *existingCalendar, const QStringList & attList, QString qName ) { int i = 1; bool skip = true; int max = attList.count() -2; while ( i < max ) { if ( !attList[i].isEmpty() ) { skip = false; break; } ++i ; } if ( skip ) return false; ulong cSum = SharpFormat::getCsum(attList ); if ( qName == "Event" ) { Event *event; event = existingCalendar->event( "Sharp_DTM",attList[0] ); if ( event ) event = (Event*)event->clone(); else event = new Event; event->setID("Sharp_DTM", attList[0] ); event->setCsum( "Sharp_DTM", QString::number( cSum )); event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); event->setSummary( attList[2] ); event->setLocation( attList[3] ); event->setDescription( attList[4] ); if ( attList[7] == "1" ) { event->setDtStart( QDateTime(fromString( attList[17]+"T000000", false ).date(),QTime(0,0,0 ) )); event->setDtEnd( QDateTime(fromString( attList[18]+"T000000", false ).date(),QTime(0,0,0 ))); event->setFloats( true ); } else { event->setFloats( false ); event->setDtStart( fromString( attList[5] ) ); event->setDtEnd( fromString( attList[6] )); } QString rtype = attList[11]; if ( rtype != "255" ) { // qDebug("recurs "); QDate startDate = event->dtStart().date(); QString freqStr = attList[12]; int freq = freqStr.toInt(); QString hasEndDateStr = attList[15] ; bool hasEndDate = hasEndDateStr == "1"; QString endDateStr = attList[16]; QDate endDate = fromString( endDateStr ).date(); QString weekDaysStr = attList[14]; uint weekDaysNum = weekDaysStr.toInt(); QBitArray weekDays( 7 ); int i; int bb = 1; for( i = 1; i <= 7; ++i ) { weekDays.setBit( i - 1, ( bb & weekDaysNum )); bb = 2 << (i-1); //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) ); } // qDebug("next "); QString posStr = attList[13]; int pos = posStr.toInt(); Recurrence *r = event->recurrence(); if ( rtype == "0" ) { if ( hasEndDate ) r->setDaily( freq, endDate ); else r->setDaily( freq, -1 ); } else if ( rtype == "1" ) { if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate ); else r->setWeekly( freq, weekDays, -1 ); } else if ( rtype == "3" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyDay, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyDay, freq, -1 ); r->addMonthlyDay( startDate.day() ); } else if ( rtype == "2" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyPos, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyPos, freq, -1 ); QBitArray days( 7 ); days.fill( false ); days.setBit( startDate.dayOfWeek() - 1 ); r->addMonthlyPos( pos, days ); } else if ( rtype == "4" ) { if ( hasEndDate ) r->setYearly( Recurrence::rYearlyMonth, freq, endDate ); else r->setYearly( Recurrence::rYearlyMonth, freq, -1 ); r->addYearlyNum( startDate.month() ); } } QString categoryList = attList[1] ; event->setCategories( lookupCategories( categoryList ) ); // strange 0 semms to mean: alarm enabled if ( attList[8] == "0" ) { Alarm *alarm; if ( event->alarms().count() > 0 ) alarm = event->alarms().first(); else { alarm = new Alarm( event ); event->addAlarm( alarm ); } alarm->setType( Alarm::Audio ); alarm->setEnabled( true ); int alarmOffset = attList[9].toInt(); alarm->setStartOffset( alarmOffset * -60 ); } mCalendar->addEvent( event); } else if ( qName == "Todo" ) { Todo *todo; todo = existingCalendar->todo( "Sharp_DTM", attList[0] ); if (todo ) todo = (Todo*)todo->clone(); else todo = new Todo; //CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1 // 0 1 2 3 4 5 6 7 8 //1,,,,,1,4,Loch zumachen,"" //3,Privat,20040317T000000,20040318T000000,20040319T000000,0,5,Call bbb,"notes123 bbb gggg ""bb "" " //2,"Familie,Freunde,Holiday",20040318T000000,20040324T000000,20040317T000000,1,2,tod2,notes todo->setID( "Sharp_DTM", attList[0]); todo->setCsum( "Sharp_DTM", QString::number( cSum )); todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); todo->setSummary( attList[7] ); todo->setDescription( attList[8]); int priority = attList[6].toInt(); if ( priority == 0 ) priority = 3; todo->setPriority( priority ); QString categoryList = attList[1]; todo->setCategories( lookupCategories( categoryList ) ); QString hasDateStr = attList[3]; // due if ( !hasDateStr.isEmpty() ) { if ( hasDateStr.right(6) == "000000" ) { todo->setDtDue( QDateTime(fromString( hasDateStr, false ).date(), QTime(0,0,0 )) ); todo->setFloats( true ); } else { todo->setDtDue( fromString( hasDateStr ) ); todo->setFloats( false ); } todo->setHasDueDate( true ); } hasDateStr = attList[2];//start if ( !hasDateStr.isEmpty() ) { todo->setDtStart( fromString( hasDateStr ) ); todo->setHasStartDate( true); } else todo->setHasStartDate( false ); hasDateStr = attList[4];//completed if ( !hasDateStr.isEmpty() ) { todo->setCompleted(fromString( hasDateStr ) ); } QString completedStr = attList[5]; if ( completedStr == "0" ) todo->setCompleted( true ); else todo->setCompleted( false ); mCalendar->addTodo( todo ); } else if ( qName == "Category" ) { /* QString id = attributes.value( "id" ); QString name = attributes.value( "name" ); setCategory( id, name ); */ } //qDebug("end "); return true; } void setCategoriesList ( QStringList * c ) { oldCategories = c; } QDateTime fromString ( QString s, bool useTz = true ) { QDateTime dt; int y,m,t,h,min,sec; y = s.mid(0,4).toInt(); m = s.mid(4,2).toInt(); t = s.mid(6,2).toInt(); h = s.mid(9,2).toInt(); min = s.mid(11,2).toInt(); sec = s.mid(13,2).toInt(); dt = QDateTime(QDate(y,m,t), QTime(h,min,sec)); int offset = KGlobal::locale()->localTimeOffset( dt ); if ( useTz ) dt = dt.addSecs ( offset*60); return dt; } protected: QDateTime toDateTime( const QString &value ) { QDateTime dt; dt.setTime_t( value.toUInt() ); return dt; } QStringList lookupCategories( const QString &categoryList ) { QStringList categoryIds = QStringList::split( ";", categoryList ); QStringList categories; QStringList::ConstIterator it; for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) { QString cate = category( *it ); if ( oldCategories ) { if ( ! oldCategories->contains( cate ) ) oldCategories->append( cate ); } categories.append(cate ); } return categories; } private: Calendar *mCalendar; QStringList * oldCategories; static QString category( const QString &id ) { QMap<QString,QString>::ConstIterator it = mCategoriesMap.find( id ); if ( it == mCategoriesMap.end() ) return id; else return *it; } static void setCategory( const QString &id, const QString &name ) { mCategoriesMap.insert( id, name ); } static QMap<QString,QString> mCategoriesMap; }; QMap<QString,QString> SharpParser::mCategoriesMap; SharpFormat::SharpFormat() { mCategories = 0; } SharpFormat::~SharpFormat() { } ulong SharpFormat::getCsum( const QStringList & attList) { int max = attList.count() -1; ulong cSum = 0; int j,k,i; int add; for ( i = 1; i < max ; ++i ) { QString s = attList[i]; if ( ! s.isEmpty() ){ j = s.length(); for ( k = 0; k < j; ++k ) { int mul = k +1; add = s[k].unicode (); if ( k < 16 ) mul = mul * mul; add = add * mul *i*i*i; cSum += add; } } } return cSum; } #include <stdlib.h> -#define DEBUGMODE true +#define DEBUGMODE false bool SharpFormat::load( Calendar *calendar, Calendar *existngCal ) { bool debug = DEBUGMODE; //debug = true; QString text; QString codec = "utf8"; QLabel status ( i18n("Reading events ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 200; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Reading DTM Data") ); status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); status.show(); status.raise(); qApp->processEvents(); QString fileName; if ( ! debug ) { fileName = "/tmp/kopitempout"; QString command ="db2file datebook -r -c "+ codec + " > " + fileName; system ( command.latin1() ); } else { fileName = "/tmp/events.txt"; } QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); text = ts.read(); file.close(); status.setText( i18n("Processing events ...") ); status.raise(); qApp->processEvents(); fromString2Cal( calendar, existngCal, text, "Event" ); status.setText( i18n("Reading todos ...") ); qApp->processEvents(); if ( ! debug ) { fileName = "/tmp/kopitempout"; QString command = "db2file todo -r -c " + codec+ " > " + fileName; system ( command.latin1() ); } else { fileName = "/tmp/todo.txt"; } file.setName( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } ts.setDevice( &file ); text = ts.read(); file.close(); status.setText( i18n("Processing todos ...") ); status.raise(); qApp->processEvents(); fromString2Cal( calendar, existngCal, text, "Todo" ); return true; } int SharpFormat::getNumFromRecord( QString answer, Incidence* inc ) { int retval = -1; QStringList templist; QString tempString; int start = 0; int len = answer.length(); int end = answer.find ("\n",start)+1; bool ok = true; start = end; int ccc = 0; while ( start > 0 ) { templist.clear(); ok = true; int loopCount = 0; while ( ok ) { ++loopCount; if ( loopCount > 25 ) { qDebug("KO: Error in while loop"); ok = false; start = 0; break; } if ( ok ) tempString = getPart( answer, ok, start ); if ( start >= len || start == 0 ) { start = 0; ok = false; } if ( tempString.right(1) =="\n" ) tempString = tempString.left( tempString.length()-1); templist.append( tempString ); } ++ccc; if ( ccc == 2 && loopCount < 25 ) { start = 0; bool ok; int newnum = templist[0].toInt( &ok ); if ( ok && newnum > 0) { retval = newnum; inc->setID( "Sharp_DTM",templist[0] ); inc->setCsum( "Sharp_DTM", QString::number( getCsum( templist ) )); inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); } } } //qDebug("getNumFromRecord returning : %d ", retval); return retval; } bool SharpFormat::save( Calendar *calendar) { QLabel status ( i18n("Processing/adding events ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 200; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Writing DTM Data") ); status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); status.show(); status.raise(); qApp->processEvents(); bool debug = DEBUGMODE; QString codec = "utf8"; QString answer; QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n"; QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n"; QString command; QPtrList<Event> er = calendar->rawEvents(); Event* ev = er.first(); QString fileName = "/tmp/kopitempout"; int i = 0; QString changeString = ePrefix; QString deleteString = ePrefix; bool deleteEnt = false; bool changeEnt = false; QString message = i18n("Processing event # "); int procCount = 0; while ( ev ) { //qDebug("i %d ", ++i); if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString eString = getEventString( ev ); if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete // deleting empty strings does not work. // we write first and x and then delete the record with the x eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); changeString += eString + "\n"; deleteString += eString + "\n"; deleteEnt = true; changeEnt = true; } else if ( ev->getID("Sharp_DTM").isEmpty() ) { // add new command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; system ( command.utf8() ); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); answer = ts.read(); file.close(); //qDebug("answer \n%s ", answer.latin1()); getNumFromRecord( answer, ev ) ; } else { // change existing //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() ); //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; changeString += eString + "\n"; changeEnt = true; } } ev = er.next(); } status.setText ( i18n("Changing events ...") ); qApp->processEvents(); //qDebug("changing... "); if ( changeEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << changeString ; file.close(); command = "db2file datebook -w -g -c " + codec+ " < "+ fileName; system ( command.latin1() ); //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); } status.setText ( i18n("Deleting events ...") ); qApp->processEvents(); //qDebug("deleting... "); if ( deleteEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << deleteString; file.close(); command = "db2file datebook -d -c " + codec+ " < "+ fileName; system ( command.latin1() ); // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); } changeString = tPrefix; deleteString = tPrefix; status.setText ( i18n("Processing todos ...") ); qApp->processEvents(); QPtrList<Todo> tl = calendar->rawTodos(); Todo* to = tl.first(); i = 0; message = i18n("Processing todo # "); procCount = 0; while ( to ) { if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString eString = getTodoString( to ); if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete // deleting empty strings does not work. // we write first and x and then delete the record with the x eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); changeString += eString + "\n"; deleteString += eString + "\n"; deleteEnt = true; changeEnt = true; } else if ( to->getID("Sharp_DTM").isEmpty() ) { // add new command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName; system ( command.utf8() ); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); answer = ts.read(); file.close(); //qDebug("answer \n%s ", answer.latin1()); getNumFromRecord( answer, to ) ; } else { // change existing //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() ); //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; changeString += eString + "\n"; changeEnt = true; } } to = tl.next(); } status.setText ( i18n("Changing todos ...") ); qApp->processEvents(); //qDebug("changing... "); if ( changeEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << changeString ; file.close(); command = "db2file todo -w -g -c " + codec+ " < "+ fileName; system ( command.latin1() ); //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); } status.setText ( i18n("Deleting todos ...") ); qApp->processEvents(); //qDebug("deleting... "); if ( deleteEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << deleteString; file.close(); command = "db2file todo -d -c " + codec+ " < "+ fileName; system ( command.latin1() ); // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); } return true; } QString SharpFormat::dtToString( const QDateTime& dti, bool useTZ ) { QString datestr; QString timestr; int offset = KGlobal::locale()->localTimeOffset( dti ); QDateTime dt; if (useTZ) dt = dti.addSecs ( -(offset*60)); else dt = dti; if(dt.date().isValid()){ const QDate& date = dt.date(); datestr.sprintf("%04d%02d%02d", date.year(), date.month(), date.day()); } if(dt.time().isValid()){ const QTime& time = dt.time(); timestr.sprintf("T%02d%02d%02d", time.hour(), time.minute(), time.second()); } return datestr + timestr; } QString SharpFormat::getEventString( Event* event ) { QStringList list; list.append( event->getID("Sharp_DTM") ); list.append( event->categories().join(",") ); if ( !event->summary().isEmpty() ) list.append( event->summary() ); else list.append("" ); if ( !event->location().isEmpty() ) list.append( event->location() ); else list.append("" ); if ( !event->description().isEmpty() ) list.append( event->description() ); else list.append( "" ); if ( event->doesFloat () ) { list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 list.append( "1" ); } else { list.append( dtToString( event->dtStart()) ); list.append( dtToString( event->dtEnd()) ); //6 list.append( "0" ); } bool noAlarm = true; if ( event->alarms().count() > 0 ) { Alarm * al = event->alarms().first(); if ( al->enabled() ) { noAlarm = false; list.append( "0" ); // yes, 0 == alarm list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); if ( al->type() == Alarm::Audio ) list.append( "1" ); // type audio else list.append( "0" ); // type silent } } if ( noAlarm ) { list.append( "1" ); // yes, 1 == no alarm list.append( "0" ); // no alarm offset list.append( "1" ); // type } // next is: 11 // next is: 11-16 are recurrence Recurrence* rec = event->recurrence(); |