-rw-r--r-- | korganizer/calendarview.cpp | 40 | ||||
-rw-r--r-- | korganizer/calendarview.h | 1 | ||||
-rw-r--r-- | korganizer/mainwindow.cpp | 6 | ||||
-rw-r--r-- | libkcal/libkcalE.pro | 2 | ||||
-rw-r--r-- | libkcal/phoneformat.cpp | 1359 | ||||
-rw-r--r-- | libkcal/phoneformat.h | 65 |
6 files changed, 1465 insertions, 8 deletions
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp index 689618d..a7f7010 100644 --- a/korganizer/calendarview.cpp +++ b/korganizer/calendarview.cpp @@ -1,277 +1,278 @@ /* This file is part of KOrganizer. Requires the Qt and KDE widget libraries, available at no cost at http://www.troll.no and http://www.kde.org respectively Copyright (c) 1997, 1998, 1999 Preston Brown (preston.brown@yale.edu) Fester Zigterman (F.J.F.ZigtermanRustenburg@student.utwente.nl) Ian Dawes (iadawes@globalserve.net) Laszlo Boloni (boloni@cs.purdue.edu) Copyright (c) 2000, 2001, 2002 Cornelius Schumacher <schumacher@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdlib.h> #include <qapplication.h> #include <qradiobutton.h> #include <qbuttongroup.h> #include <qlayout.h> #include <qclipboard.h> #include <qcursor.h> #include <qmessagebox.h> #include <qprogressbar.h> #include <qmultilineedit.h> #include <qtimer.h> #include <qwidgetstack.h> #include <qptrlist.h> #include <qregexp.h> #include <qgroupbox.h> #include <qfile.h> #include <qdir.h> #ifndef KORG_NOSPLITTER #include <qsplitter.h> #endif #include <kglobal.h> #include <kdebug.h> #include <kstandarddirs.h> #include <kfiledialog.h> #include <kmessagebox.h> #include <knotifyclient.h> #include <kconfig.h> #include <libkdepim/ksyncprefsdialog.h> #include <krun.h> #include <kdirwatch.h> #include <libkdepim/kdatepicker.h> #include <libkdepim/ksyncprofile.h> #include <libkcal/vcaldrag.h> #include <libkcal/icaldrag.h> #include <libkcal/icalformat.h> #include <libkcal/vcalformat.h> #include <libkcal/scheduler.h> #include <libkcal/calendarlocal.h> #include <libkcal/journal.h> #include <libkcal/calfilter.h> #include <libkcal/attendee.h> #include <libkcal/dndfactory.h> #include <libkcal/freebusy.h> #include <libkcal/filestorage.h> #include <libkcal/calendarresources.h> #include <libkcal/qtopiaformat.h> #include "../kalarmd/alarmdialog.h" #ifndef DESKTOP_VERSION #include <libkcal/sharpformat.h> #endif +#include <libkcal/phoneformat.h> #ifndef KORG_NOMAIL #include "komailclient.h" #endif #ifndef KORG_NOPRINTER #include "calprinter.h" #endif #ifndef KORG_NOPLUGINS #include "kocore.h" #endif #include "koeventeditor.h" #include "kotodoeditor.h" #include "koprefs.h" #include "koeventviewerdialog.h" #include "publishdialog.h" #include "kofilterview.h" #include "koglobals.h" #include "koviewmanager.h" #include "koagendaview.h" #include "kodialogmanager.h" #include "outgoingdialog.h" #include "incomingdialog.h" #include "statusdialog.h" #include "kdatenavigator.h" #include "kotodoview.h" #include "datenavigator.h" #include "resourceview.h" #include "navigatorbar.h" #include "searchdialog.h" #include "mainwindow.h" #include "calendarview.h" #ifndef DESKTOP_VERSION #include <qtopia/alarmserver.h> #endif #ifndef _WIN32_ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #else #include <qprocess.h> #endif using namespace KOrg; using namespace KCal; extern int globalFlagBlockAgenda; extern int globalFlagBlockStartup; class KOBeamPrefs : public QDialog { public: KOBeamPrefs( QWidget *parent=0, const char *name=0 ) : QDialog( parent, name, true ) { setCaption( i18n("Beam Options") ); QVBoxLayout* lay = new QVBoxLayout( this ); lay->setSpacing( 3 ); lay->setMargin( 3 ); QButtonGroup* format = new QButtonGroup( 1, Horizontal, i18n("File format"), this ); lay->addWidget( format ); format->setExclusive ( true ) ; QButtonGroup* time = new QButtonGroup(1, Horizontal, i18n("Time format"), this ); lay->addWidget( time ); time->setExclusive ( true ) ; vcal = new QRadioButton(" vCalendar ", format ); ical = new QRadioButton(" iCalendar ", format ); vcal->setChecked( true ); tz = new QRadioButton(i18n(" With timezone "), time ); local = new QRadioButton(i18n(" Local time "), time ); tz->setChecked( true ); QPushButton * ok = new QPushButton( i18n("Beam via IR!"), this ); lay->addWidget( ok ); QPushButton * cancel = new QPushButton( i18n("Cancel"), this ); lay->addWidget( cancel ); connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) ); connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) ); resize( 200, 200 ); } bool beamVcal() { return vcal->isChecked(); } bool beamLocal() { return local->isChecked(); } private: QRadioButton* vcal, *ical, *local, *tz; }; class KOCatPrefs : public QDialog { public: KOCatPrefs( QWidget *parent=0, const char *name=0 ) : QDialog( parent, name, true ) { setCaption( i18n("Manage new Categories") ); QVBoxLayout* lay = new QVBoxLayout( this ); lay->setSpacing( 3 ); lay->setMargin( 3 ); QLabel * lab = new QLabel( i18n("After importing/loading/syncing\nthere may be new categories in\nevents or todos\nwhich are not in the category list.\nPlease choose what to do:\n "), this ); lay->addWidget( lab ); QButtonGroup* format = new QButtonGroup( 1, Horizontal, i18n("New categories not in list:"), this ); lay->addWidget( format ); format->setExclusive ( true ) ; addCatBut = new QRadioButton(i18n("Add to category list"), format ); new QRadioButton(i18n("Remove from Events/Todos"), format ); addCatBut->setChecked( true ); QPushButton * ok = new QPushButton( i18n("OK"), this ); lay->addWidget( ok ); QPushButton * cancel = new QPushButton( i18n("Cancel"), this ); lay->addWidget( cancel ); connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) ); connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) ); resize( 200, 200 ); } bool addCat() { return addCatBut->isChecked(); } private: QRadioButton* addCatBut; }; CalendarView::CalendarView( CalendarResources *calendar, QWidget *parent, const char *name ) : CalendarViewBase( parent, name ), mCalendar( calendar ), mResourceManager( calendar->resourceManager() ) { mEventEditor = 0; mTodoEditor = 0; init(); } CalendarView::CalendarView( Calendar *calendar, QWidget *parent, const char *name ) : CalendarViewBase( parent, name ), mCalendar( calendar ), mResourceManager( 0 ) { mEventEditor = 0; mTodoEditor = 0; init();} void CalendarView::init() { beamDialog = new KOBeamPrefs(); mDatePickerMode = 0; mCurrentSyncDevice = ""; writeLocale(); mViewManager = new KOViewManager( this ); mDialogManager = new KODialogManager( this ); mEventViewerDialog = 0; mModified = false; mReadOnly = false; mSelectedIncidence = 0; mCalPrinter = 0; mFilters.setAutoDelete(true); mCalendar->registerObserver( this ); // TODO: Make sure that view is updated, when calendar is changed. mStorage = new FileStorage( mCalendar ); mNavigator = new DateNavigator( this, "datevav", mViewManager ); QBoxLayout *topLayout = (QBoxLayout*)layout(); #ifndef KORG_NOSPLITTER // create the main layout frames. mPanner = new QSplitter(QSplitter::Horizontal,this,"CalendarView::Panner"); topLayout->addWidget(mPanner); mLeftSplitter = new QSplitter(QSplitter::Vertical,mPanner, "CalendarView::LeftFrame"); mPanner->setResizeMode(mLeftSplitter,QSplitter::KeepSize); mDateNavigator = new KDateNavigator(mLeftSplitter, mCalendar, TRUE, "CalendarView::DateNavigator", QDate::currentDate() ); mLeftSplitter->setResizeMode(mDateNavigator,QSplitter::KeepSize); mTodoList = new KOTodoView(mCalendar, mLeftSplitter, "todolist_small2"); mFilterView = new KOFilterView(&mFilters,mLeftSplitter,"CalendarView::FilterView"); #ifdef KORG_NORESOURCEVIEW mResourceView = 0; #else if ( mResourceManager ) { mResourceView = new ResourceView( mResourceManager, mLeftSplitter ); mResourceView->updateView(); connect( mResourceView, SIGNAL( resourcesChanged() ), SLOT( updateView() ) ); } else { mResourceView = 0; } #endif QWidget *rightBox = new QWidget( mPanner ); QBoxLayout *rightLayout = new QVBoxLayout( rightBox ); @@ -986,448 +987,471 @@ bool CalendarView::synchronizeCalendar( Calendar* local, Calendar* remote, int 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::syncPhone() { - qDebug("CalendarView::syncPhone() "); + syncExternal( 1 ); } -void CalendarView::syncSharp() +void CalendarView::syncExternal( int mode ) { -#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 ) ) { + boo loadSuccess = false; + PhoneFormat* phoneFormat = 0; +#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 (); + loadSuccess = phoneFormat->load( calendar, mCalendar ); + + } else + return; + if ( loadSuccess ) { 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); +#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 ); } } } 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 + +} +void CalendarView::syncSharp() +{ + syncExternal( 0 ); + } #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 ); } QString kind; if ( birthday ) kind = i18n( "Birthday" ); else kind = i18n( "Anniversary" ); ev->setSummary( name + " - " + kind ); ev->setOrganizer( "nobody@nowhere" ); ev->setCategories( kind ); ev->setDtStart( QDateTime(date) ); ev->setDtEnd( QDateTime(date) ); ev->setFloats( true ); Recurrence * rec = ev->recurrence(); rec->setYearly(Recurrence::rYearlyMonth,1,-1); rec->addYearlyNum( date.month() ); if ( !mCalendar->addAnniversaryNoDup( ev ) ) { delete ev; return false; } return true; } bool CalendarView::importQtopia( const QString &categories, const QString &datebook, const QString &todolist ) { QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories ); if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook ); if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist ); updateView(); return true; #if 0 mGlobalSyncMode = SYNC_MODE_QTOPIA; mCurrentSyncDevice = "qtopia-XML"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); bool loadOk = true; if ( !categories.isEmpty() ) loadOk = qtopiaFormat.load( calendar, categories ); if ( loadOk && !datebook.isEmpty() ) loadOk = qtopiaFormat.load( calendar, datebook ); if ( loadOk && !todolist.isEmpty() ) loadOk = qtopiaFormat.load( calendar, todolist ); if ( loadOk ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { // write back XML file } setModified( true ); } } else { QString question = i18n("Sorry, the file loading\ncommand failed!\n\nNothing synced!\n") ; QMessageBox::information( 0, i18n("KO/Pi Sync - ERROR"), question, i18n("Ok")) ; } delete calendar; updateView(); return syncOK; #endif } void CalendarView::setSyncEventsReadOnly() { Event * ev; QPtrList<Event> eL = mCalendar->rawEvents(); ev = eL.first(); while ( ev ) { if ( ev->uid().left(15) == QString("last-syncEvent-") ) ev->setReadOnly( true ); ev = eL.next(); } } bool CalendarView::openCalendar(QString filename, bool merge) { if (filename.isEmpty()) { return false; } if (!QFile::exists(filename)) { KMessageBox::error(this,i18n("File does not exist:\n '%1'.").arg(filename)); return false; } globalFlagBlockAgenda = 1; if (!merge) mCalendar->close(); mStorage->setFileName( filename ); if ( mStorage->load(KOPrefs::instance()->mUseQuicksave) ) { if ( merge ) ;//setModified( true ); else { //setModified( true ); mViewManager->setDocumentId( filename ); mDialogManager->setDocumentId( filename ); mTodoList->setDocumentId( filename ); } globalFlagBlockAgenda = 2; // if ( getLastSyncEvent() ) // getLastSyncEvent()->setReadOnly( true ); mCalendar->reInitAlarmSettings(); setSyncEventsReadOnly(); updateUnmanagedViews(); updateView(); if ( filename != MainWindow::defaultFileName() ) saveCalendar( MainWindow::defaultFileName() ); loadedFileVersion = QDateTime::currentDateTime(); return true; } else { // while failing to load, the calendar object could // have become partially populated. Clear it out. if ( !merge ) mCalendar->close(); KMessageBox::error(this,i18n("Couldn't load calendar\n '%1'.").arg(filename)); globalFlagBlockAgenda = 2; diff --git a/korganizer/calendarview.h b/korganizer/calendarview.h index b2838db..a3315ad 100644 --- a/korganizer/calendarview.h +++ b/korganizer/calendarview.h @@ -237,353 +237,354 @@ class CalendarView : public KOrg::CalendarViewBase, public KCal::Calendar::Obser bool deleteEvent(const QString &uid); /** Create a read-only viewer dialog for the supplied event. */ void showEvent(Event *); void editJournal(Journal *); void showJournal(Journal *); void deleteJournal(Journal *); /** Create an editor dialog for a todo */ void editTodo(Todo *); /** Create a read-only viewer dialog for the supplied todo */ void showTodo(Todo *); /** create new todo */ void newTodo(); /** create new todo with a parent todo */ void newSubTodo(); /** create new todo with a parent todo */ void newSubTodo(Todo *); /** Delete todo */ void deleteTodo(Todo *); /** Check if clipboard contains vCalendar event. The signal pasteEnabled() is * emitted as result. */ void checkClipboard(); /** using the KConfig associated with the kapp variable, read in the * settings from the config file. */ void readSettings(); /** write current state to config file. */ void writeSettings(); /** read settings for calendar filters */ void readFilterSettings(KConfig *config); /** write settings for calendar filters */ void writeFilterSettings(KConfig *config); /** passes on the message that an event has changed to the currently * activated view so that it can make appropriate display changes. */ void changeEventDisplay(Event *, int); void changeIncidenceDisplay(Incidence *, int); void changeTodoDisplay(Todo *, int); void eventAdded(Event *); void eventChanged(Event *); void eventToBeDeleted(Event *); void eventDeleted(); void todoAdded(Todo *); void todoChanged(Todo *); void todoToBeDeleted(Todo *); void todoDeleted(); void updateView(const QDate &start, const QDate &end); void updateView(); /** Full update of visible todo views */ void updateTodoViews(); void updateUnmanagedViews(); /** cut the current appointment to the clipboard */ void edit_cut(); /** copy the current appointment(s) to the clipboard */ void edit_copy(); /** paste the current vobject(s) in the clipboard buffer into calendar */ void edit_paste(); /** edit viewing and configuration options. */ void edit_options(); void edit_sync_options(); /** Functions for printing, previewing a print, and setting up printing parameters. */ void print(); void printSetup(); void printPreview(); /** Export as iCalendar file */ void exportICalendar(); /** Export as vCalendar file */ bool exportVCalendar( QString fn); /** pop up a dialog to show an existing appointment. */ void appointment_show(); /** * pop up an Appointment Dialog to edit an existing appointment. Get * information on the appointment from the list of unique IDs that is * currently in the View, called currIds. */ void appointment_edit(); /** * pop up dialog confirming deletion of currently selected event in the * View. */ void appointment_delete(); /** mails the currently selected event to a particular user as a vCalendar attachment. */ void action_mail(); /* frees a subtodo from it's relation */ void todo_unsub( Todo * ); /** Take ownership of selected event. */ void takeOverEvent(); /** Take ownership of all events in calendar. */ void takeOverCalendar(); /** query whether or not the calendar is "dirty". */ bool isModified(); /** set the state of calendar. Modified means "dirty", i.e. needing a save. */ void setModified(bool modified=true); /** query if the calendar is read-only. */ bool isReadOnly(); /** set state of calendar to read-only */ void setReadOnly(bool readOnly=true); void eventUpdated(Incidence *); /* iTIP scheduling actions */ void schedule_publish(Incidence *incidence = 0); void schedule_request(Incidence *incidence = 0); void schedule_refresh(Incidence *incidence = 0); void schedule_cancel(Incidence *incidence = 0); void schedule_add(Incidence *incidence = 0); void schedule_reply(Incidence *incidence = 0); void schedule_counter(Incidence *incidence = 0); void schedule_declinecounter(Incidence *incidence = 0); void schedule_publish_freebusy(int daysToPublish = 30); void openAddressbook(); void editFilters(); void toggleFilerEnabled(); QPtrList<CalFilter> filters(); void toggleFilter(); void showFilter(bool visible); void updateFilter(); void filterEdited(); void selectFilter( int ); KOFilterView *filterView(); void showIntro(); /** Move the curdatepient view date to today */ void goToday(); /** Move to the next date(s) in the current view */ void goNext(); /** Move to the previous date(s) in the current view */ void goPrevious(); /** Move to the next date(s) in the current view */ void goNextMonth(); /** Move to the previous date(s) in the current view */ void goPreviousMonth(); void toggleExpand(); void toggleDateNavigatorWidget(); void toggleAllDaySize(); void dialogClosing(Incidence *); /** Look for new messages in the inbox */ void lookForIncomingMessages(); /** Look for new messages in the outbox */ void lookForOutgoingMessages(); void processMainViewSelection( Incidence * ); void processTodoListSelection( Incidence * ); void processIncidenceSelection( Incidence * ); void purgeCompleted(); bool removeCompletedSubTodos( Todo* ); void slotCalendarChanged(); bool importBday(); bool addAnniversary( QDate data, QString name, KCal::Attendee* a , bool birthday ); bool importQtopia( const QString &categoriesFile, const QString &datebookFile, const QString &tasklistFile ); void syncSharp( ); void syncPhone( ); + void syncExternal( int mode ); void slotSelectPickerDate( QDate ) ; void showDatePicker( ) ; void moveIncidence(Incidence *) ; void beamIncidence(Incidence *) ; void beamCalendar() ; void beamFilteredCalendar() ; void beamIncidenceList(QPtrList<Incidence>) ; void manageCategories(); int addCategories(); void removeCategories(); void setSyncDevice( QString ); void setSyncName( QString ); protected slots: void timerAlarm(); void suspendAlarm(); void beamDone( Ir *ir ); /** Select a view or adapt the current view to display the specified dates. */ void showDates( const KCal::DateList & ); void selectWeekNum ( int ); public: // show a standard warning // returns KMsgBox::yesNoCancel() int msgCalModified(); void confSync(); void setLoadedFileVersion(QDateTime); bool checkFileVersion(QString fn); bool checkFileChanged(QString fn); Event* getLastSyncEvent(); /** Adapt navigation units correpsonding to step size of navigation of the * current view. */ void adaptNavigationUnits(); bool synchronizeCalendar( Calendar* local, Calendar* remote, int mode ); int takeEvent( Incidence* local, Incidence* remote, int mode, bool full = false ); //Attendee* getYourAttendee(Event *event); protected: void schedule(Scheduler::Method, Incidence *incidence = 0); // returns KMsgBox::OKCandel() int msgItemDelete(); void showEventEditor(); void showTodoEditor(); void writeLocale(); Todo *selectedTodo(); private: AlarmDialog * mAlarmDialog; QString mAlarmNotification; QString mSuspendAlarmNotification; QTimer* mSuspendTimer; QTimer* mAlarmTimer; QTimer* mRecheckAlarmTimer; void computeAlarm( QString ); void startAlarm( QString, QString ); void setSyncEventsReadOnly(); QDateTime loadedFileVersion; void checkExternSyncEvent( QPtrList<Event> lastSync , Incidence* toDelete ); void checkExternalId( Incidence * inc ); int mGlobalSyncMode; QString mCurrentSyncDevice; QString mCurrentSyncName; KOBeamPrefs* beamDialog; void init(); int mDatePickerMode; bool mFlagEditDescription; QDateTime mLastCalendarSync; void createPrinter(); void calendarModified( bool, Calendar * ); CalPrinter *mCalPrinter; QSplitter *mPanner; QSplitter *mLeftSplitter; QWidget *mLeftFrame; QWidgetStack *mRightFrame; KDatePicker* mDatePicker; QVBox* mDateFrame; NavigatorBar *mNavigatorBar; KDateNavigator *mDateNavigator; // widget showing small month view. KOFilterView *mFilterView; ResourceView *mResourceView; // calendar object for this viewing instance Calendar *mCalendar; CalendarResourceManager *mResourceManager; FileStorage *mStorage; DateNavigator *mNavigator; KOViewManager *mViewManager; KODialogManager *mDialogManager; // Calendar filters QPtrList<CalFilter> mFilters; // various housekeeping variables. bool mModified; // flag indicating if calendar is modified bool mReadOnly; // flag indicating if calendar is read-only QDate mSaveSingleDate; Incidence *mSelectedIncidence; Incidence *mMoveIncidence; QPtrList<Event> mExternLastSyncEvent; KOTodoView *mTodoList; KOEventEditor * mEventEditor; KOTodoEditor * mTodoEditor; KOEventViewerDialog * mEventViewerDialog; void keyPressEvent ( QKeyEvent *e) ; //QMap<Incidence*,KOIncidenceEditor*> mDialogList; }; class CalendarViewVisitor : public Incidence::Visitor { public: CalendarViewVisitor() : mView( 0 ) {} bool act( Incidence *incidence, CalendarView *view ) { mView = view; return incidence->accept( *this ); } protected: CalendarView *mView; }; class ShowIncidenceVisitor : public CalendarViewVisitor { protected: bool visit( Event *event ) { mView->showEvent( event ); return true; } bool visit( Todo *todo ) { mView->showTodo( todo ); return true; } bool visit( Journal * j ) { mView->showJournal( j );return true; } }; class EditIncidenceVisitor : public CalendarViewVisitor { protected: bool visit( Event *event ) { mView->editEvent( event ); return true; } bool visit( Todo *todo ) { mView->editTodo( todo ); return true; } bool visit( Journal *j ) { mView->editJournal( j); return true; } }; class DeleteIncidenceVisitor : public CalendarViewVisitor { protected: bool visit( Event *event ) { mView->deleteEvent( event ); return true; } bool visit( Todo *todo ) { mView->deleteTodo( todo ); return true; } bool visit( Journal * j) {mView->deleteJournal( j ); return true; } }; #endif diff --git a/korganizer/mainwindow.cpp b/korganizer/mainwindow.cpp index 062c95f..cce182a 100644 --- a/korganizer/mainwindow.cpp +++ b/korganizer/mainwindow.cpp @@ -811,384 +811,390 @@ void MainWindow::initActions() if (p-> mShowIconWhatsThis) configureToolBarMenu->setItemChecked( 300, true ); QLabel* dummy = new QLabel( iconToolBar ); dummy->setBackgroundColor( iconToolBar->backgroundColor() ); if (!p-> mShowIconStretch) iconToolBar->setStretchableWidget ( dummy ) ; else configureToolBarMenu->setItemChecked( 5, true ); if (p-> mShowIconWhatsThis) QWhatsThis::whatsThisButton ( iconToolBar ); connect( configureToolBarMenu, SIGNAL( activated( int ) ),this, SLOT(configureToolBar( int ) ) ); configureAgenda( p->mHourSize ); connect( configureAgendaMenu, SIGNAL( activated( int ) ),this, SLOT(configureAgenda( int ) ) ); } void MainWindow::fillSyncMenu() { syncMenu->clear(); syncMenu->insertItem( i18n("Configure..."), 0 ); syncMenu->insertSeparator(); syncMenu->insertItem( i18n("Multiple sync"), 1 ); syncMenu->insertSeparator(); KConfig config ( locateLocal( "config","syncprofilesrc" ) ); config.setGroup("General"); QStringList prof = config.readListEntry("SyncProfileNames"); KOPrefs::instance()->mLocalMachineName = config.readEntry("LocalMachineName","undefined"); if ( prof.count() < 3 ) { prof.clear(); prof << i18n("Sharp_DTM"); prof << i18n("Local_file"); prof << i18n("Last_file"); KSyncProfile* temp = new KSyncProfile (); temp->setName( prof[0] ); temp->writeConfig(&config); temp->setName( prof[1] ); temp->writeConfig(&config); temp->setName( prof[2] ); temp->writeConfig(&config); config.setGroup("General"); config.writeEntry("SyncProfileNames",prof); config.writeEntry("ExternSyncProfiles","Sharp_DTM"); config.sync(); delete temp; } KOPrefs::instance()->mExternSyncProfiles = config.readListEntry("ExternSyncProfiles"); KOPrefs::instance()->mSyncProfileNames = prof; int i; for ( i = 0; i < prof.count(); ++i ) { syncMenu->insertItem( prof[i], 1000+i ); if ( i == 2 ) syncMenu->insertSeparator(); } QDir app_dir; if ( !app_dir.exists(QDir::homeDirPath()+"/Applications/dtm" ) ) { syncMenu->setItemEnabled( false , 1000 ); } mView->setupExternSyncProfiles(); } int MainWindow::ringSync() { int syncedProfiles = 0; int i; QTime timer; KConfig config ( locateLocal( "config","syncprofilesrc" ) ); QStringList syncProfileNames = KOPrefs::instance()->mSyncProfileNames; KSyncProfile* temp = new KSyncProfile (); KOPrefs::instance()->mAskForPreferences = false; for ( i = 0; i < syncProfileNames.count(); ++i ) { mCurrentSyncProfile = i; temp->setName(syncProfileNames[mCurrentSyncProfile]); temp->readConfig(&config); if ( temp->getIncludeInRingSync() && ( i < 1 || i > 2 )) { setCaption(i18n("Profile ")+syncProfileNames[mCurrentSyncProfile]+ i18n(" is synced ... ")); ++syncedProfiles; // KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); KOPrefs::instance()->mShowSyncSummary = false; mView->setSyncDevice(syncProfileNames[i] ); mView->setSyncName( KOPrefs::instance()->mLocalMachineName ); if ( i == 0 ) { syncSharp(); } else { if ( temp->getIsLocalFileSync() ) { if ( syncWithFile( temp->getRemoteFileName( ), true ) ) KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); } else { if ( temp->getIsPhoneSync() ) { KOPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ; KOPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( ); KOPrefs::instance()->mPhoneModel = temp->getPhoneModel( ); syncPhone(); } else syncRemote( temp, false ); } } timer.start(); setCaption(i18n("Multiple sync in progress ... please wait!") ); while ( timer.elapsed () < 2000 ) { qApp->processEvents(); #ifndef _WIN32_ sleep (1); #endif } } } delete temp; return syncedProfiles; } void MainWindow::multiSync( bool askforPrefs ) { if (mBlockSaveFlag) return; mBlockSaveFlag = true; QString question = i18n("Do you really want\nto multiple sync\nwith all checked profiles?\nSyncing takes some\ntime - all profiles\nare synced twice!"); if ( QMessageBox::information( this, i18n("KO/Pi Sync"), question, i18n("Yes"), i18n("No"), 0, 0 ) != 0 ) { mBlockSaveFlag = false; setCaption(i18n("Aborted! Nothing synced!")); return; } mView->setSyncDevice(i18n("Multiple profiles") ); KOPrefs::instance()->mSyncAlgoPrefs = KOPrefs::instance()->mRingSyncAlgoPrefs; if ( askforPrefs ) { mView->edit_sync_options(); KOPrefs::instance()->mRingSyncAlgoPrefs = KOPrefs::instance()->mSyncAlgoPrefs; } setCaption(i18n("Multiple sync started.") ); qApp->processEvents(); int num = ringSync() ; if ( num > 1 ) ringSync(); mBlockSaveFlag = false; if ( num ) save(); if ( num ) setCaption(i18n("%1 profiles synced. Multiple sync completed!").arg(num) ); else setCaption(i18n("Nothing synced! No profiles defined for multisync!")); return; } void MainWindow::slotSyncMenu( int action ) { //qDebug("syncaction %d ", action); if ( action == 0 ) { confSync(); return; } if ( action == 1 ) { multiSync( true ); return; } if (mBlockSaveFlag) return; mBlockSaveFlag = true; mCurrentSyncProfile = action - 1000 ; mView->setSyncDevice(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile] ); mView->setSyncName( KOPrefs::instance()->mLocalMachineName ); KConfig config ( locateLocal( "config","syncprofilesrc" ) ); KSyncProfile* temp = new KSyncProfile (); temp->setName(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); temp->readConfig(&config); KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); KOPrefs::instance()->mSyncAlgoPrefs = temp->getSyncPrefs(); KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); KOPrefs::instance()->mShowSyncSummary = temp->getShowSummaryAfterSync(); if ( action == 1000 ) { syncSharp(); } else if ( action == 1001 ) { syncLocalFile(); } else if ( action == 1002 ) { quickSyncLocalFile(); } else if ( action >= 1003 ) { if ( temp->getIsLocalFileSync() ) { if ( syncWithFile( temp->getRemoteFileName( ), false ) ) KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); } else { + if ( temp->getIsPhoneSync() ) { + KOPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ; + KOPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( ); + KOPrefs::instance()->mPhoneModel = temp->getPhoneModel( ); + syncPhone(); + } else syncRemote( temp ); } } delete temp; mBlockSaveFlag = false; } void MainWindow::setDefaultPreferences() { KOPrefs *p = KOPrefs::instance(); p->mCompactDialogs = true; p->mConfirm = true; // p->mEnableQuickTodo = false; } QString MainWindow::resourcePath() { return KGlobal::iconLoader()->iconPath(); } void MainWindow::displayText( QString text ,QString cap ) { QDialog dia( this, "name", true ); ; dia.setCaption( cap ); QVBoxLayout* lay = new QVBoxLayout( &dia ); lay->setSpacing( 3 ); lay->setMargin( 3 ); QTextBrowser tb ( &dia ); lay->addWidget( &tb ); tb.setText( text ); #ifdef DESKTOP_VERSION dia.resize( 640, 480); #else dia.showMaximized(); #endif dia.exec(); } void MainWindow::displayFile( QString fn, QString cap ) { QString fileName = resourcePath() + fn; QString text; QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return ; } QTextStream ts( &file ); text = ts.read(); file.close(); displayText( text, cap); } void MainWindow::features() { displayFile( "featuresKOPI.txt",i18n("KO/Pi Features and hints") ); } void MainWindow::usertrans() { displayFile( "usertranslationHOWTO.txt",i18n("KO/Pi User translation HowTo") ); } void MainWindow::synchowto() { displayFile( "howtoSYNC.txt",i18n("KO/Pi Synchronization HowTo") ); } void MainWindow::faq() { displayFile( "kopiFAQ.txt",i18n("KO/Pi FAQ") ); } void MainWindow::whatsNew() { displayFile( "kopiWhatsNew.txt",i18n("KO/Pi Version Info") ); } void MainWindow::licence() { KApplication::showLicence(); } void MainWindow::about() { QString version; #include <../version> QMessageBox::about( this, i18n("About KOrganizer/Pi"), i18n("KOrganizer/Platform-independent\n") + "(KO/Pi) " + version + " - " + #ifdef DESKTOP_VERSION i18n("Desktop Edition\n") + #else i18n("PDA-Edition\nfor: Zaurus 5x00 / 7x0 / 8x0\n") + #endif i18n("(c) 2004 Lutz Rogowski\nEmail:lutz@pi-sync.net\nKO/Pi is based on KOrganizer\n(c) 2002,2003 Cornelius Schumacher\nEmail: schumacher@kde.org\nKOrganizer/Pi is licensed\nunder the GPL.\nKO/Pi can be compiled for\nLinux, Zaurus-PDA and Windows\nwww.korganizer.org\nwww.pi-sync.net\n") ); } void MainWindow::keyBindings() { QString cap = i18n("Key bindings KOrganizer/Pi"); QString text = i18n("<p><h2>KO/Pi key shortcuts:</h2></p>\n") + i18n("<p><b>H</b>: This help dialog | <b>S</b>: Search dialog</p>\n")+ i18n("<p><b>I</b>: Show info for selected event/todo</p>\n") + i18n("<p><b>Space</b>: Toggle fullscreen | <b>P</b>: Date picker</p>\n")+ i18n("<p><b>F</b>: Toggle filterview |<b>F+ctrl</b>: Edit filter </p>\n")+ i18n("<p><b>O</b>: Filter On/Off | <b>J</b>: Journal view</p>\n")+ i18n("<p><b>1-0</b> (+<b>ctrl</b>): Select filter 1-10 (11-20)</p>\n")+ i18n("<p><b>N</b>: Next days view| <b>W</b>: What's next view\n ")+ i18n("<p><b>V</b>: Todo view | <b>L</b>: Event list view</p>\n")+ i18n("<p><b>Z,Y</b>: Work week view | <b>U</b>: Week view</p>\n")+ i18n("<p><b>D</b>: One day view | <b>M</b>: Month view</p>\n")+ i18n("<p><b>E</b>: Edit selected item |<b> E+ctrl</b>: New Event</p>\n")+ i18n("<p><b>T</b>: Goto today | <b>T+ctrl</b>: New Todo</p>\n")+ i18n("<p><b>S+ctrl</b>: Add sub-todo | <b>X</b>: Toggle datenavigator</p>\n")+ i18n("<p><b>+,-</b> : Zoom in/out agenda | <b>A</b>: Toggle allday agenda height</p>\n")+ i18n("<p><b>C</b>: Show current time in agenda view</p>\n")+ i18n("<p><b>B</b>: Edit description (details) of selected item</p>\n")+ i18n("<p><b>right</b>: Next week | <b>right+ctrl</b>: Next month</p>\n")+ i18n("<p><b>left</b>: Prev. week | <b>left+ctrl</b>: Prev. month</p>\n")+ i18n("<p><b>del,backspace</b>: Delete selected item</p>\n")+ i18n("<p><h3>In agenda view:</h3></p>\n") + i18n("<p><b>up/down</b>: Scroll agenda view</p>\n")+ i18n("<p><b>ctrl+up/down</b>: Scroll small todo view</p>\n")+ i18n("<p><h3>In todo view:</h3></p>\n") + i18n("<p><b>Q</b>: Toggle quick todo line edit.</p>\n")+ i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+ i18n("<p><b>return</b>: Mark item as completed+one step down.</p>\n")+ i18n("<p><b>return+shift</b>: Mark item as not completed+one step down</p>\n")+ i18n("<p><h3>In list view:</h3></p>\n") + i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+ i18n("<p><b>return</b>: Select item+one step down</p>\n")+ i18n("<p><b>return+shift</b>: Deselect item+one step down</p>\n")+ i18n("<p><b>up/down</b>: Next/prev item</p>\n")+ i18n("<p><b>ctrl+up/down</b>: Goto up/down by 20% of items</p>\n")+ i18n("<p><b>shift+up/down</b>: Goto first/last item</p>\n")+ i18n("<p><h3>In event/todo viewer:</h3></p>\n") + i18n("<p><b>I,C</b>: Close dialog.</p>\n")+ i18n("<p><b>A</b>: Show agenda view.</p>\n")+ i18n("<p><b>E</b>: Edit item</p>\n") + i18n("<p><h2>KO/Pi icon colors:</h2></p>\n") + i18n("<p><b>(for square icons in agenda and month view)</b></p>\n") + i18n("<p><b>Cross</b>: Item cancelled.([c] in Whats'Next view)</p>\n")+ i18n("<p><b>Red</b>: Alarm set.([a] in Whats'Next view)</p>\n")+ i18n("<p><b>Blue</b>: Recurrent event.([r] in Whats'Next view)</p>\n")+ i18n("<p><b>Dark green</b>: Information(description) available.([i] in WN view)</p>\n")+ i18n("<p><b>Black</b>: Event/todo with attendees. You are the organizer!</p>\n")+ i18n("<p><b>Dark yellow</b>: Event/todo with attendees.</p>\n") + i18n("<p><b>White</b>: Item readonly</p>\n"); displayText( text, cap); } void MainWindow::aboutAutoSaving() { QMessageBox* msg; msg = new QMessageBox( i18n("Auto Saving in KOrganizer/Pi"), i18n("After changing something, the data is\nautomatically saved to the file\n~/kdepim/apps/korganizer/mycalendar.ics\nafter (configureable) three minutes.\nFor safety reasons there is one autosaving\nafter 10 minutes (of idle time) again. The \ndata is saved automatically when closing KO/Pi\nYou can create a backup file \nwith: File - Save Calendar Backup\n"), QMessageBox::NoIcon, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); msg->exec(); delete msg; } void MainWindow::aboutKnownBugs() { QMessageBox* msg; msg = new QMessageBox( i18n("Known Problems in KOrganizer/Pi"), i18n("1) Importing *.vcs or *.ics files from\nother applications may not work properly,\nif there are events with properties\nKO/Pi does not support.\n")+ i18n("2) Audio alarm daemon\nfor Zaurus is available!\nas an additional small application\n")+ i18n("\nPlease report unexpected behaviour to\nlutz@pi-sync.net\n") + i18n("\nor report them in the bugtracker on\n") + i18n("\nhttp://sourceforge.net/projects/kdepimpi\n"), QMessageBox::NoIcon, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); msg->exec(); delete msg; } QString MainWindow::defaultFileName() { return locateLocal( "data", "korganizer/mycalendar.ics" ); } void MainWindow::processIncidenceSelection( Incidence *incidence ) { if ( !incidence ) { enableIncidenceActions( false ); diff --git a/libkcal/libkcalE.pro b/libkcal/libkcalE.pro index 283a22d..f5be980 100644 --- a/libkcal/libkcalE.pro +++ b/libkcal/libkcalE.pro @@ -1,87 +1,89 @@ TEMPLATE = lib CONFIG += qt warn_on TARGET = microkcal INCLUDEPATH += ../microkde ../qtcompat versit ../microkde/kdecore $(QPEDIR)/include INCLUDEPATH += ../libical/src/libical INCLUDEPATH += ../libical/src/libicalss OBJECTS_DIR = obj/$(PLATFORM) MOC_DIR = moc/$(PLATFORM) DESTDIR = $(QPEDIR)/lib LIBS += ../libical/lib/$(PLATFORM)/libical.a LIBS += ../libical/lib/$(PLATFORM)/libicalss.a INTERFACES = \ HEADERS = \ alarm.h \ attachment.h \ attendee.h \ calendar.h \ calendarlocal.h \ calfilter.h \ calformat.h \ calstorage.h \ compat.h \ customproperties.h \ dummyscheduler.h \ duration.h \ event.h \ exceptions.h \ filestorage.h \ freebusy.h \ icaldrag.h \ icalformat.h \ icalformatimpl.h \ imipscheduler.h \ incidence.h \ incidencebase.h \ journal.h \ period.h \ person.h \ qtopiaformat.h \ sharpformat.h \ + phoneformat.h \ recurrence.h \ scheduler.h \ todo.h \ vcaldrag.h \ vcalformat.h \ versit/port.h \ versit/vcc.h \ versit/vobject.h \ SOURCES = \ alarm.cpp \ attachment.cpp \ attendee.cpp \ calendar.cpp \ calendarlocal.cpp \ calfilter.cpp \ calformat.cpp \ compat.cpp \ customproperties.cpp \ dummyscheduler.cpp \ duration.cpp \ event.cpp \ exceptions.cpp \ filestorage.cpp \ freebusy.cpp \ icaldrag.cpp \ icalformat.cpp \ icalformatimpl.cpp \ imipscheduler.cpp \ incidence.cpp \ incidencebase.cpp \ journal.cpp \ period.cpp \ person.cpp \ qtopiaformat.cpp \ sharpformat.cpp \ + phoneformat.cpp \ recurrence.cpp \ scheduler.cpp \ todo.cpp \ vcaldrag.cpp \ vcalformat.cpp \ versit/vcc.c \ versit/vobject.c \ diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp new file mode 100644 index 0000000..f78730d --- a/dev/null +++ b/libkcal/phoneformat.cpp @@ -0,0 +1,1359 @@ +/* + 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 "phoneformat.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( attList[0].toInt() ); + if ( event ) + event = (Event*)event->clone(); + else + event = new Event; + event->setZaurusId( attList[0].toInt() ); + event->setZaurusUid( cSum ); + event->setZaurusStat( -2 ); + + 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( attList[0].toInt() ); + 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->setZaurusId( attList[0].toInt() ); + todo->setZaurusUid( cSum ); + todo->setZaurusStat( -2 ); + + 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; + +} +//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum); +#include <stdlib.h> +#define DEBUGMODE false +bool SharpFormat::load( Calendar *calendar, Calendar *existngCal ) +{ + + GSM_StateMachine s; + qDebug(" load "); + s.opened = false; + s.msg = NULL; + s.ConfigNum = 0; +static char *cp; + static INI_Section *cfg = NULL; + cfg=GSM_FindGammuRC(); + int i; + for (i = 0; i <= MAX_CONFIG_NUM; i++) { + if (cfg!=NULL) { + cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false); + if (cp) di.coding = cp; + + s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false); + if (s.Config[i].Localize) { + s.msg=INI_ReadFile(s.Config[i].Localize, true); + } else { +#if !defined(WIN32) && defined(LOCALE_PATH) + locale = setlocale(LC_MESSAGES, NULL); + if (locale != NULL) { + snprintf(locale_file, 200, "%s/gammu_%c%c.txt", + LOCALE_PATH, + tolower(locale[0]), + tolower(locale[1])); + s.msg = INI_ReadFile(locale_file, true); + } +#endif + } + } + + /* Wanted user specific configuration? */ + + if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; + + s.ConfigNum++; + + /* We want to use only one file descriptor for global and state machine debug output */ + s.Config[i].UseGlobalDebugFile = true; + + + + /* We wanted to read just user specified configuration. */ + {break;} + } + + + + + int error=GSM_InitConnection(&s,3); + + + qDebug(" init %d %d", error, ERR_NONE); + if ( error != ERR_NONE ) + return false; + fromString2Cal( calendar, existngCal, &s, "Event" ); + + + error=GSM_TerminateConnection(&s); + + +#if 0 + + 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" ); +#endif + 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->setZaurusId( newnum ); + inc->setZaurusUid( getCsum( templist ) ); + inc->setZaurusStat( -4 ); + } + } + } + //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->zaurusStat() != -2 ) { + status.setText ( message + QString::number ( ++procCount ) ); + qApp->processEvents(); + QString eString = getEventString( ev ); + if ( ev->zaurusStat() == -3 ) { // 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->zaurusId() == -1 ) { // 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->zaurusStat() != -2 ) { + status.setText ( message + QString::number ( ++procCount ) ); + qApp->processEvents(); + QString eString = getTodoString( to ); + if ( to->zaurusStat() == -3 ) { // 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->zaurusId() == -1 ) { // 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( QString::number(event->zaurusId() ) ); + list.append( event->categories().join(",") ); + if ( !event->summary().isEmpty() ) + list.append( event->summary() ); + else + list.append("" ); + if ( !event->location().isEmpty() ) + list.append( event->location() ); + else + list.append("" ); + if ( !event->description().isEmpty() ) + list.append( event->description() ); + else + list.append( "" ); + if ( event->doesFloat () ) { + list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); + list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 + list.append( "1" ); + + } + else { + list.append( dtToString( event->dtStart()) ); + list.append( dtToString( event->dtEnd()) ); //6 + list.append( "0" ); + } + bool noAlarm = true; + if ( event->alarms().count() > 0 ) { + Alarm * al = event->alarms().first(); + if ( al->enabled() ) { + noAlarm = false; + list.append( "0" ); // yes, 0 == alarm + list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); + if ( al->type() == Alarm::Audio ) + list.append( "1" ); // type audio + else + list.append( "0" ); // type silent + } + } + if ( noAlarm ) { + list.append( "1" ); // yes, 1 == no alarm + list.append( "0" ); // no alarm offset + list.append( "1" ); // type + } + // next is: 11 + // next is: 11-16 are recurrence + Recurrence* rec = event->recurrence(); + + bool writeEndDate = false; + switch ( rec->doesRecur() ) + { + case Recurrence::rDaily: // 0 + list.append( "0" ); + list.append( QString::number( rec->frequency() ));//12 + list.append( "0" ); + list.append( "0" ); + writeEndDate = true; + break; + case Recurrence::rWeekly:// 1 + list.append( "1" ); + list.append( QString::number( rec->frequency()) );//12 + list.append( "0" ); + { + int days = 0; + QBitArray weekDays = rec->days(); + int i; + for( i = 1; i <= 7; ++i ) { + if ( weekDays[i-1] ) { + days += 1 << (i-1); + } + } + list.append( QString::number( days ) ); + } + //pending weekdays + writeEndDate = true; + + break; + case Recurrence::rMonthlyPos:// 2 + list.append( "2" ); + list.append( QString::number( rec->frequency()) );//12 + + writeEndDate = true; + { + int count = 1; + QPtrList<Recurrence::rMonthPos> rmp; + rmp = rec->monthPositions(); + if ( rmp.first()->negative ) + count = 5 - rmp.first()->rPos - 1; + else + count = rmp.first()->rPos - 1; + list.append( QString::number( count ) ); + + } + + list.append( "0" ); + break; + case Recurrence::rMonthlyDay:// 3 + list.append( "3" ); + list.append( QString::number( rec->frequency()) );//12 + list.append( "0" ); + list.append( "0" ); + writeEndDate = true; + break; + case Recurrence::rYearlyMonth://4 + list.append( "4" ); + list.append( QString::number( rec->frequency()) );//12 + list.append( "0" ); + list.append( "0" ); + writeEndDate = true; + break; + + default: + list.append( "255" ); + list.append( QString() ); + list.append( "0" ); + list.append( QString() ); + list.append( "0" ); + list.append( "20991231T000000" ); + break; + } + if ( writeEndDate ) { + + if ( rec->endDate().isValid() ) { // 15 + 16 + list.append( "1" ); + list.append( dtToString( rec->endDate()) ); + } else { + list.append( "0" ); + list.append( "20991231T000000" ); + } + + } + if ( event->doesFloat () ) { + list.append( dtToString( event->dtStart(), false ).left( 8 )); + list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6 + + } + else { + list.append( QString() ); + list.append( QString() ); + + } + if (event->dtStart().date() == event->dtEnd().date() ) + list.append( "0" ); + else + list.append( "1" ); + + + for(QStringList::Iterator it=list.begin(); + it!=list.end(); ++it){ + QString& s = (*it); + s.replace(QRegExp("\""), "\"\""); + if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ + s.prepend('\"'); + s.append('\"'); + } else if(s.isEmpty() && !s.isNull()){ + s = "\"\""; + } + } + return list.join(","); + + +} +QString SharpFormat::getTodoString( Todo* todo ) +{ + QStringList list; + list.append( QString::number( todo->zaurusId() ) ); + list.append( todo->categories().join(",") ); + + if ( todo->hasStartDate() ) { + list.append( dtToString( todo->dtStart()) ); + } else + list.append( QString() ); + + if ( todo->hasDueDate() ) { + QTime tim; + if ( todo->doesFloat()) { + list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; + } else { + list.append( dtToString(todo->dtDue() ) ); + } + } else + list.append( QString() ); + + if ( todo->isCompleted() ) { + list.append( dtToString( todo->completed()) ); + list.append( "0" ); // yes 0 == completed + } else { + list.append( dtToString( todo->completed()) ); + list.append( "1" ); + } + list.append( QString::number( todo->priority() )); + if( ! todo->summary().isEmpty() ) + list.append( todo->summary() ); + else + list.append( "" ); + if (! todo->description().isEmpty() ) + list.append( todo->description() ); + else + list.append( "" ); + for(QStringList::Iterator it=list.begin(); + it!=list.end(); ++it){ + QString& s = (*it); + s.replace(QRegExp("\""), "\"\""); + if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ + s.prepend('\"'); + s.append('\"'); + } else if(s.isEmpty() && !s.isNull()){ + s = "\"\""; + } + } + return list.join(","); +} +QString SharpFormat::getPart( const QString & text, bool &ok, int &start ) +{ + //qDebug("start %d ", start); + + QString retval =""; + if ( text.at(start) == '"' ) { + if ( text.mid( start,2) == "\"\"" && !( text.mid( start+2,1) == "\"")) { + start = start +2; + if ( text.mid( start,1) == "," ) { + start += 1; + } + retval = ""; + if ( text.mid( start,1) == "\n" ) { + start += 1; + ok = false; + } + return retval; + } + int hk = start+1; + hk = text.find ('"',hk); + while ( text.at(hk+1) == '"' ) + hk = text.find ('"',hk+2); + retval = text.mid( start+1, hk-start-1); + start = hk+1; + retval.replace( QRegExp("\"\""), "\""); + if ( text.mid( start,1) == "," ) { + start += 1; + } + if ( text.mid( start,1) == "\n" ) { + start += 1; + ok = false; + } + //qDebug("retval***%s*** ",retval.latin1() ); + return retval; + + } else { + int nl = text.find ("\n",start); + int kom = text.find (',',start); + if ( kom < nl ) { + // qDebug("kom < nl %d ", kom); + retval = text.mid(start, kom-start); + start = kom+1; + return retval; + } else { + if ( nl == kom ) { + // qDebug(" nl == kom "); + start = 0; + ok = false; + return "0"; + } + // qDebug(" nl < kom ", nl); + retval = text.mid( start, nl-start); + ok = false; + start = nl+1; + return retval; + } + } +} +bool SharpFormat::fromString( Calendar *calendar, const QString & text) +{ + return false; +} +bool SharpFormat::fromString2Cal( Calendar *calendar,Calendar *existingCalendar, GSM_StateMachine* s, const QString & type) +{ + GSM_Phone_Functions *Phone; + + GSM_CalendarEntry note; + GSM_CalendarEntry* Note; + bool refresh = true; + + Phone=s->Phone.Functions; + bool gshutdown = false; + SharpParser handler( calendar ); + //handler.setCategoriesList( mCategories ); + QStringList templist; + QString tempString; + int start = 0; + int error; + int ccc = 0; + while (!gshutdown && ccc++ < 10 ) { + QString CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY; + templist.clear(); + qDebug("count %d ", ccc); + error=Phone->GetNextCalendar(s,¬e,refresh); + if (error == ERR_EMPTY) break; + + Note = ¬e; +//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 + + CARDID = QString::number( Note->Location ); // 0 + + + int i_age = 0,i; + GSM_DateTime Alarm,DateTime; + GSM_DateTime* dtp; + GSM_MemoryEntry entry; + unsigned char *name; + + bool repeating = false; + int repeat_dayofweek = -1; + int repeat_day = -1; + int repeat_weekofmonth = -1; + int repeat_month = -1; + int repeat_frequency = -1; + GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; + GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; + + Alarm.Year = 0; + + repeating = false; + repeat_dayofweek = -1; + repeat_day = -1; + repeat_weekofmonth = -1; + repeat_month = -1; + repeat_frequency = -1; + repeat_startdate.Day = 0; + repeat_stopdate.Day = 0; + + + switch (Note->Type) { + case GSM_CAL_REMINDER : CATEGORY = QString("Reminder"); break; + case GSM_CAL_CALL : CATEGORY = QString("Call"); break; + case GSM_CAL_MEETING : CATEGORY = QString("Meeting"); break; + case GSM_CAL_BIRTHDAY : CATEGORY = QString("Birthday"); break; + case GSM_CAL_MEMO : CATEGORY = QString("Memo"); break; + case GSM_CAL_TRAVEL : CATEGORY = QString("Travel"); break; + case GSM_CAL_VACATION : CATEGORY = QString("Vacation"); break; + case GSM_CAL_ALARM : CATEGORY = QString("Alarm"); break; + case GSM_CAL_DAILY_ALARM : CATEGORY = QString("Daily alarm"); break; + case GSM_CAL_T_ATHL : CATEGORY = QString("Training/Athletism"); break; + case GSM_CAL_T_BALL : CATEGORY = QString("Training/Ball Games"); break; + case GSM_CAL_T_CYCL : CATEGORY = QString("Training/Cycling"); break; + case GSM_CAL_T_BUDO : CATEGORY = QString("Training/Budo"); break; + case GSM_CAL_T_DANC : CATEGORY = QString("Training/Dance"); break; + case GSM_CAL_T_EXTR : CATEGORY = QString("Training/Extreme Sports"); break; + case GSM_CAL_T_FOOT : CATEGORY = QString("Training/Football"); break; + case GSM_CAL_T_GOLF : CATEGORY = QString("Training/Golf"); break; + case GSM_CAL_T_GYM : CATEGORY = QString("Training/Gym"); break; + case GSM_CAL_T_HORS : CATEGORY = QString("Training/Horse Races"); break; + case GSM_CAL_T_HOCK : CATEGORY = QString("Training/Hockey"); break; + case GSM_CAL_T_RACE : CATEGORY = QString("Training/Races"); break; + case GSM_CAL_T_RUGB : CATEGORY = QString("Training/Rugby"); break; + case GSM_CAL_T_SAIL : CATEGORY = QString("Training/Sailing"); break; + case GSM_CAL_T_STRE : CATEGORY = QString("Training/Street Games"); break; + case GSM_CAL_T_SWIM : CATEGORY = QString("Training/Swimming"); break; + case GSM_CAL_T_TENN : CATEGORY = QString("Training/Tennis"); break; + case GSM_CAL_T_TRAV : CATEGORY = QString("Training/Travels"); break; + case GSM_CAL_T_WINT : CATEGORY = QString("Training/Winter Games"); break; + default : CATEGORY = QString(""); + } +//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY +// 0x 1x 2x 3x 4x 5x 6x 7x 8x 9x 10? 11 12 13 14 15 16 17x 18x 19? + + MEM1 = ""; + +#if 0 + + if ( attList[7] == "1" ) { + event->setDtStart( QDateTime(fromString( attList[17]+"000000", false ).date(),QTime(0,0,0 ) )); + event->setDtEnd( QDateTime(fromString( attList[18]+"000000", false ).date(),QTime(0,0,0 ))); + event->setFloats( true ); + } else { + event->setFloats( false ); + event->setDtStart( fromString( attList[5] ) ); + event->setDtEnd( fromString( attList[6] )); + } + + + +typedef struct { + /** + * The difference between local time and GMT in hours + */ + int Timezone; + + unsigned int Second; + unsigned int Minute; + unsigned int Hour; + + unsigned int Day; + /** + * January = 1, February = 2, etc. + */ + unsigned int Month; + /** + * Complete year number. Not 03, but 2003 + */ + unsigned int Year; +} GSM_DateTime; + + 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; + + + + +#endif + + + ADAY = "0"; + ARON = "1"; // 1 == disabled + ARMN = "0"; //alarm offset in minutes + + for (i=0;i<Note->EntriesNum;i++) { + + qDebug(" for "); + switch (Note->Entries[i].EntryType) { + case CAL_START_DATETIME: + dtp = &Note->Entries[i].Date ; + + qDebug("hour: %d ", dtp->Hour); + if ( dtp->Hour == -1 ) { + ADAY = "1"; + ALSD.sprintf("%04d%02d%02d",dtp->Year, dtp->Month, dtp->Day ); + TIM1.sprintf("%04d%02d%02dT000000",dtp->Year, dtp->Month, dtp->Day ); + } else { + TIM1.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second ); + + } + ////printmsg("Start : %s\n",OSDateTime(Note->Entries[i].Date,false)); + // memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime)); + break; + case CAL_END_DATETIME: + dtp = &Note->Entries[i].Date ; + qDebug("hour2: %d ", dtp->Hour); + if ( dtp->Hour == -1 ) { + ADAY = "1"; + ALED.sprintf("%04d%02d%02d",dtp->Year, dtp->Month, dtp->Day ); + TIM2.sprintf("%04d%02d%02dT000000",dtp->Year, dtp->Month, dtp->Day ); + } else { + TIM2.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second ); + + } + //printmsg("Stop : %s\n",OSDateTime(Note->Entries[i].Date,false)); + //memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime)); + break; + case CAL_ALARM_DATETIME: + ARON = "0"; + dtp = &Note->Entries[i].Date ; + ARMN.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second ); + //printmsg("Tone alarm : %s\n",OSDateTime(Note->Entries[i].Date,false)); + memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime)); + break; + case CAL_SILENT_ALARM_DATETIME: + ARON = "0"; + dtp = &Note->Entries[i].Date ; + ARMN.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second ); + //printmsg("Silent alarm : %s\n",OSDateTime(Note->Entries[i].Date,false)); + //memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime)); + break; + case CAL_RECURRANCE: + //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" ); + break; + case CAL_TEXT: + DSRP = QString ( (const char*) Note->Entries[i].Text ); + break; + case CAL_LOCATION: + PLCE = QString ((const char*) Note->Entries[i].Text ); + break; + case CAL_PHONE: + //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); + break; + case CAL_PRIVATE: + //printmsg("Private : %s\n",Note->Entries[i].Number == 1 ? "Yes" : "No"); + break; + case CAL_CONTACTID: +#if 0 + entry.Location = Note->Entries[i].Number; + entry.MemoryType = MEM_ME; + error=Phone->GetMemory(&s, &entry); + if (error == ERR_NONE) { + name = GSM_PhonebookGetEntryName(&entry); + if (name != NULL) { + //printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number); + } else { + //printmsg("Contact ID : %d\n",Note->Entries[i].Number); + } + } else { + //printmsg("Contact ID : %d\n",Note->Entries[i].Number); + } +#endif + break; + case CAL_REPEAT_DAYOFWEEK: + repeat_dayofweek = Note->Entries[i].Number; + repeating = true; + break; + case CAL_REPEAT_DAY: + repeat_day = Note->Entries[i].Number; + repeating = true; + break; + case CAL_REPEAT_WEEKOFMONTH: + repeat_weekofmonth = Note->Entries[i].Number; + repeating = true; + break; + case CAL_REPEAT_MONTH: + repeat_month = Note->Entries[i].Number; + repeating = true; + break; + case CAL_REPEAT_FREQUENCY: + repeat_frequency = Note->Entries[i].Number; + repeating = true; + break; + case CAL_REPEAT_STARTDATE: + repeat_startdate = Note->Entries[i].Date; + repeating = true; + break; + case CAL_REPEAT_STOPDATE: + repeat_stopdate = Note->Entries[i].Date; + repeating = true; + break; + } + } + + + + if ( ARON == "0" ) { + QDateTime start,alarm; + start = handler.fromString( TIM1 ); + alarm = handler.fromString( ARMN ); + int min = alarm.secsTo ( start )/60; + ARMN = QString::number ( min ); + } + + templist.clear(); + templist << CARDID << CATEGORY << DSRP << PLCE << MEM1 << TIM1 << TIM2 << ADAY << ARON << ARMN << ARSD << RTYP << RFRQ << RPOS << RDYS << REND << REDT << ALSD << ALED << MDAY; + handler.startElement( existingCalendar, templist, type ); + } + + + +#if 0 + // qDebug("test %s ", text.latin1()); + QStringList templist; + QString tempString; + int start = 0; + int len = text.length(); + int end = text.find ("\n",start)+1; + bool ok = true; + start = end; + SharpParser handler( calendar ); + handler.setCategoriesList( mCategories ); + while ( start > 0 ) { + templist.clear(); + ok = true; + while ( ok ) { + tempString = getPart( text, ok, start ); + if ( start >= len || start == 0 ) { + start = 0; + ok = false; + } + if ( tempString.right(1) =="\n" ) + tempString = tempString.left( tempString.length()-1); + //if ( ok ) + templist.append( tempString ); + //qDebug("%d ---%s---", templist.count(),tempString.latin1() ); + } + handler.startElement( existingCalendar, templist, type ); + } +#endif + return false; +} + +QString SharpFormat::toString( Calendar * ) +{ + return QString::null; +} diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h new file mode 100644 index 0000000..f4cb52c --- a/dev/null +++ b/libkcal/phoneformat.h @@ -0,0 +1,65 @@ +/* + This file is part of libkcal. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef SHARPFORMAT_H +#define SHARPAFORMAT_H + +#include <qstring.h> + +#include "scheduler.h" + +#include "calformat.h" +extern "C" { +#include "gammu.h" +} + +namespace KCal { + +/** + This class implements the calendar format used by Sharp. +*/ + +class SharpFormat : public QObject { + public: + /** Create new iCalendar format. */ + SharpFormat(); + virtual ~SharpFormat(); + + bool load( Calendar * ,Calendar *); + bool save( Calendar * ); + void setCategoriesList ( QStringList * cat ){ mCategories = cat; } + bool fromString2Cal( Calendar *, Calendar *, GSM_StateMachine* s , const QString & ); + bool fromString( Calendar *, const QString & ); + QString toString( Calendar * ); + static ulong getCsum( const QStringList & ); + + private: + QString getEventString( Event* ); + QString getTodoString( Todo* ); + QString dtToString( const QDateTime& dt, bool useTZ = true ); + + QStringList *mCategories; + int getNumFromRecord( QString answer,Incidence* inc ) ; + QString getPart( const QString & text, bool &ok, int &start ); +}; + +} + +#endif |