-rw-r--r-- | libkcal/phoneformat.cpp | 319 | ||||
-rw-r--r-- | libkcal/phoneformat.h | 13 |
2 files changed, 154 insertions, 178 deletions
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp index 596148e..b8fed47 100644 --- a/libkcal/phoneformat.cpp +++ b/libkcal/phoneformat.cpp @@ -1,1186 +1,1159 @@ /* 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" #include "syncdefines.h" using namespace KCal; class PhoneParser : public QObject { public: PhoneParser( Calendar *calendar, QString profileName ) : mCalendar( calendar ), mProfileName ( profileName ) { ; } bool readTodo( Calendar *existingCalendar,GSM_ToDoEntry *ToDo, GSM_StateMachine* s) { int id = ToDo->Location; Todo *todo; todo = existingCalendar->todo( mProfileName ,QString::number( id ) ); if (todo ) todo = (Todo *)todo->clone(); else todo = new Todo; todo->setID( mProfileName,QString::number( id ) ); todo->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); int priority; switch (ToDo->Priority) { case GSM_Priority_Low : priority = 1; break; case GSM_Priority_Medium : priority = 3; break; case GSM_Priority_High : priority = 5; break; default :priority = 3 ; break; } todo->setPriority( priority ); GSM_Phone_Functions *Phone; Phone=s->Phone.Functions; int j; GSM_DateTime* dtp; bool alarm = false; QDateTime alarmDt; GSM_Category Category; int error; QString completedString = "no"; for (j=0;j<ToDo->EntriesNum;j++) { //qDebug(" for todo %d",ToDo->Location ); switch (ToDo->Entries[j].EntryType) { case TODO_END_DATETIME: dtp = &ToDo->Entries[j].Date ; todo->setDtDue (fromGSM ( dtp )); break; case TODO_COMPLETED: if ( ToDo->Entries[j].Number == 1 ) { todo->setCompleted( true ); completedString = "yes"; } else { todo->setCompleted( false ); } break; case TODO_ALARM_DATETIME: dtp = &ToDo->Entries[j].Date ; alarm = true; alarmDt = fromGSM ( dtp ); break; case TODO_SILENT_ALARM_DATETIME: dtp = &ToDo->Entries[j].Date ; alarm = true; alarmDt = fromGSM ( dtp ); break; case TODO_TEXT: //qDebug(" text *%s* ", (const char*) DecodeUnicodeConsole(ToDo->Entries[j].Text )); todo->setSummary( QString::fromUtf8 ( (const char*)DecodeUnicodeConsole(ToDo->Entries[j].Text ))); break; case TODO_PRIVATE: if ( ToDo->Entries[j].Number == 1 ) todo->setSecrecy( Incidence::SecrecyPrivate ); else todo->setSecrecy( Incidence::SecrecyPublic ); break; case TODO_CATEGORY: Category.Location = ToDo->Entries[j].Number; Category.Type = Category_ToDo; error=Phone->GetCategory(s, &Category); if (error == ERR_NONE) { QStringList cat = todo->categories(); QString nCat = QString ( (const char*)Category.Name ); if ( !nCat.isEmpty() ) if ( !cat.contains( nCat )) { cat << nCat; todo->setCategories( cat ); } } break; case TODO_CONTACTID: #if 0 // not supported entry.Location = ToDo->Entries[j].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), ToDo->Entries[j].Number); } else { printmsg("Contact ID : %d\n",ToDo->Entries[j].Number); } } else { printmsg("Contact : %d\n",ToDo->Entries[j].Number); } #endif break; case TODO_PHONE: #if 0 // not supported printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(ToDo->Entries[j].Text)); #endif break; } } QString alarmString = "na"; if ( alarm ) { Alarm *alarm; if ( todo->alarms().count() > 0 ) alarm = todo->alarms().first(); else { alarm = new Alarm( todo ); todo->addAlarm( alarm ); } alarm->setType( Alarm::Audio ); alarm->setEnabled( true ); int alarmOffset = alarmDt.secsTo( todo->dtStart() ); alarm->setStartOffset( -alarmOffset ); alarmString = QString::number( alarmOffset ); } else { Alarm *alarm; if ( todo->alarms().count() > 0 ) { alarm = todo->alarms().first(); alarm->setType( Alarm::Audio ); alarm->setStartOffset( -60*15 ); alarm->setEnabled( false ); } } // csum ***************************************** QStringList attList; uint cSum; if ( todo->hasDueDate() ) attList << dtToString ( todo->dtDue() ); attList << QString::number( id ); attList << todo->summary(); attList << completedString; attList << QString::number( todo->priority() ); attList << alarmString; attList << todo->categoriesStr(); attList << todo->secrecyStr(); cSum = PhoneFormat::getCsum(attList ); todo->setCsum( mProfileName, QString::number( cSum )); + todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); mCalendar->addTodo( todo); return true; } bool readEvent( Calendar *existingCalendar, GSM_CalendarEntry* Note) { int id = Note->Location; Event *event; event = existingCalendar->event( mProfileName ,QString::number( id ) ); if ( event ) event = (Event*)event->clone(); else event = new Event; event->setID( mProfileName,QString::number( id ) ); event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); int i = 0; bool repeating = false; int repeat_dayofweek = -1; int repeat_day = -1; int repeat_weekofmonth = -1; int repeat_month = -1; int repeat_frequency = -1; int rec_type = -1; GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; GSM_DateTime* dtp; bool alarm = false; QDateTime alarmDt; repeat_startdate.Day = 0; repeat_stopdate.Day = 0; for (i=0;i<Note->EntriesNum;i++) { //qDebug(" for ev"); switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: dtp = &Note->Entries[i].Date ; if ( dtp->Hour > 24 ) { event->setFloats( true ); event->setDtStart( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); } else { event->setDtStart (fromGSM ( dtp )); } break; case CAL_END_DATETIME: dtp = &Note->Entries[i].Date ; if ( dtp->Hour > 24 ) { event->setFloats( true ); event->setDtEnd( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); } else { event->setDtEnd (fromGSM ( dtp )); } break; case CAL_ALARM_DATETIME: dtp = &Note->Entries[i].Date ; alarm = true; alarmDt = fromGSM ( dtp ); break; case CAL_SILENT_ALARM_DATETIME: dtp = &Note->Entries[i].Date ; alarm = true; alarmDt = fromGSM ( dtp ); break; case CAL_RECURRANCE: rec_type = Note->Entries[i].Number; //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" ); break; case CAL_TEXT: //qDebug(" ev text %s", DecodeUnicodeConsole(Note->Entries[i].Text) ); event->setSummary( QString::fromUtf8 ( (const char*)DecodeUnicodeConsole( Note->Entries[i].Text ))); break; case CAL_LOCATION: event->setLocation(QString::fromUtf8 ((const char*) DecodeUnicodeConsole(Note->Entries[i].Text) )); break; case CAL_PHONE: //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); break; case CAL_PRIVATE: if ( Note->Entries[i].Number == 1 ) event->setSecrecy( Incidence::SecrecyPrivate ); else event->setSecrecy( Incidence::SecrecyPublic ); 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 0 event->setDescription( attList[4] ); 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}; #endif QString recurString = "no"; if ( repeating && repeat_frequency != -1) { recurString = "y"; if ( repeat_dayofweek >= 0 ) recurString += "dow" + QString::number (repeat_dayofweek); if ( repeat_day >= 0 ) recurString += "d" + QString::number (repeat_day); if ( repeat_weekofmonth >= 0 ) recurString += "w" + QString::number (repeat_weekofmonth); if ( repeat_month >= 0 ) recurString += "m" + QString::number ( repeat_month ); if ( repeat_frequency >= 0 ) recurString += "f" + QString::number (repeat_frequency ); int rtype = 0; // qDebug("recurs "); QDate startDate, endDate; if ( repeat_startdate.Day > 0 ) { startDate = datefromGSM ( &repeat_startdate ); event->setDtStart(QDateTime ( startDate, event->dtStart().time())); } else { startDate = event->dtStart().date(); } int freq = repeat_frequency; bool hasEndDate = false; if ( repeat_stopdate.Day > 0 ) { endDate = datefromGSM ( &repeat_stopdate ); hasEndDate = true; } uint weekDaysNum = repeat_dayofweek ; // 1 == monday, 7 == sunday 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 "); int pos = 0; Recurrence *r = event->recurrence(); /* 0 daily; 1 weekly;x 2 monthpos;x 3 monthlyday; 4 rYearlyMont bool repeating = false; int repeat_dayofweek = -1; int repeat_day = -1; int repeat_weekofmonth = -1; int repeat_month = -1; int repeat_frequency = -1; */ int dayOfWeek = startDate.dayOfWeek(); if ( repeat_weekofmonth >= 0 ) { rtype = 2; // ************************ 2 MonthlyPos pos = repeat_weekofmonth; if ( repeat_dayofweek >= 0 ) dayOfWeek = repeat_dayofweek; if (repeat_month > 0) { if ( repeat_month != event->dtStart().date().month() ) { QDate date (event->dtStart().date().year(),repeat_month,event->dtStart().date().day() ); event->setDtStart(QDateTime ( date , event->dtStart().time()) ); } if ( freq == 1 ) freq = 12; } } else if ( repeat_dayofweek >= 0 ) { rtype = 1;// ************************ 1 Weekly } else if ( repeat_day >= 0 ) { if ( repeat_month > 0) { rtype = 4; } else { rtype = 3; } } else { rtype = 0 ; } 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( 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() ); } } else { event->recurrence()->unsetRecurs(); } QStringList categoryList; categoryList << getCategory( Note ); event->setCategories( categoryList ); QString alarmString = "na"; // strange 0 semms to mean: alarm enabled if ( alarm ) { 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 = alarmDt.secsTo( event->dtStart() ); alarm->setStartOffset( -alarmOffset ); alarmString = QString::number( alarmOffset ); } else { Alarm *alarm; if ( event->alarms().count() > 0 ) { alarm = event->alarms().first(); alarm->setType( Alarm::Audio ); alarm->setStartOffset( -60*15 ); alarm->setEnabled( false ); } } // csum ***************************************** QStringList attList; uint cSum; attList << dtToString ( event->dtStart() ); attList << dtToString ( event->dtEnd() ); attList << QString::number( id ); attList << event->summary(); attList << event->location(); attList << alarmString; attList << recurString; attList << event->categoriesStr(); attList << event->secrecyStr(); cSum = PhoneFormat::getCsum(attList ); event->setCsum( mProfileName, QString::number( cSum )); + event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); mCalendar->addEvent( event); return true; } QDateTime fromGSM ( GSM_DateTime* dtp, bool useTz = true ) { QDateTime dt; int y,m,t,h,min,sec; y = dtp->Year; m = dtp->Month; t = dtp->Day; h = dtp->Hour; min = dtp->Minute; sec = dtp->Second; dt = QDateTime(QDate(y,m,t), QTime(h,min,sec)); // dtp->Timezone: offset in hours int offset = KGlobal::locale()->localTimeOffset( dt ); if ( useTz ) dt = dt.addSecs ( offset*60); return dt; } QString dtToString( const QDateTime& dti, bool useTZ = false ) { 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; } QDate datefromGSM ( GSM_DateTime* dtp ) { return QDate ( dtp->Year, dtp->Month, dtp->Day ); } QString getCategory( GSM_CalendarEntry* Note) { QString CATEGORY; 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(""); } return CATEGORY; } protected: private: Calendar *mCalendar; QString mProfileName ; }; -PhoneFormat::PhoneFormat() +PhoneFormat::PhoneFormat(QString profileName, QString device,QString connection, QString model ) { - ; + mProfileName = profileName; + mDevice = device; + mConnection = connection; + mModel = model; } PhoneFormat::~PhoneFormat() { } +int PhoneFormat::initDevice(GSM_StateMachine *s) +{ + GSM_ReadConfig(NULL, &s->Config[0], 0); + s->ConfigNum = 1; + GSM_Config *cfg = &s->Config[0]; + if ( ! mConnection.isEmpty() ) { + cfg->Connection = strdup(mConnection.latin1()); + cfg->DefaultConnection = false; + qDebug("Connection set %s ", cfg->Connection ); + + } + if ( ! mDevice.isEmpty() ) { + cfg->Device = strdup(mDevice.latin1()); + cfg->DefaultDevice = false; + qDebug("Device set %s ", cfg->Device); + + } + if ( ! mModel.isEmpty() ) { + strcpy(cfg->Model,mModel.latin1() ); + cfg->DefaultModel = false; + qDebug("Model set %s ",cfg->Model ); + } + int error=GSM_InitConnection(s,3); + return error; +} ulong PhoneFormat::getCsum( const QStringList & attList) { int max = attList.count() -1; ulong cSum = 0; int j,k,i; int add; for ( i = 1; i < max ; ++i ) { QString s = attList[i]; if ( ! s.isEmpty() ){ j = s.length(); for ( k = 0; k < j; ++k ) { int mul = k +1; add = s[k].unicode (); if ( k < 16 ) mul = mul * mul; add = add * mul *i*i*i; cSum += add; } } } return cSum; } //extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum); #include <stdlib.h> #define DEBUGMODE false -bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal ,QString profileName, QString device,QString connection, QString model ) +bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal) { - mProfileName = profileName; GSM_StateMachine s; qDebug(" load "); s.opened = false; s.msg = NULL; s.ConfigNum = 0; #if 0 static char *cp; static INI_Section *cfg = NULL; cfg=GSM_FindGammuRC(); int i; for (i = 0; i <= MAX_CONFIG_NUM; i++) { if (cfg!=NULL) { cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false); if (cp) di.coding = cp; s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false); if (s.Config[i].Localize) { s.msg=INI_ReadFile(s.Config[i].Localize, true); } else { #if !defined(WIN32) && defined(LOCALE_PATH) locale = setlocale(LC_MESSAGES, NULL); if (locale != NULL) { snprintf(locale_file, 200, "%s/gammu_%c%c.txt", LOCALE_PATH, tolower(locale[0]), tolower(locale[1])); s.msg = INI_ReadFile(locale_file, true); } #endif } } /* Wanted user specific configuration? */ if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; s.ConfigNum++; /* We want to use only one file descriptor for global and state machine debug output */ s.Config[i].UseGlobalDebugFile = true; /* We wanted to read just user specified configuration. */ {break;} } #endif - setlocale(LC_ALL, ""); - GSM_ReadConfig(NULL, &s.Config[0], 0); - s.ConfigNum = 1; - GSM_Config *cfg = &s.Config[0]; - if ( ! connection.isEmpty() ) { - cfg->Connection = strdup(connection.latin1()); - cfg->DefaultConnection = false; - qDebug("Connection set %s ", cfg->Connection ); - - } - if ( ! device.isEmpty() ) { - cfg->Device = strdup(device.latin1()); - cfg->DefaultDevice = false; - qDebug("Device set %s ", cfg->Device); - - } - if ( ! model.isEmpty() ) { - strcpy(cfg->Model,model.latin1() ); - cfg->DefaultModel = false; - qDebug("Model set %s ",cfg->Model ); - - - } - int error=GSM_InitConnection(&s,3); + int error=initDevice(&s); qDebug("GSM Init %d (no error is %d)", error, ERR_NONE); if ( error != ERR_NONE ) return false; GSM_Phone_Functions *Phone; GSM_CalendarEntry note; bool start = true; Phone=s.Phone.Functions; bool gshutdown = false; - PhoneParser handler( calendar, profileName ); + PhoneParser handler( calendar, mProfileName ); int ccc = 0; qDebug("Debug: only 10 calender items are downloaded "); while (!gshutdown && ccc++ < 10) { qDebug("readEvent %d ", ccc); error=Phone->GetNextCalendar(&s,¬e,start); if (error == ERR_EMPTY) break; start = false; handler.readEvent( existingCal, ¬e ); } start = true; GSM_ToDoEntry ToDo; ccc = 0; while (!gshutdown) { error = Phone->GetNextToDo(&s, &ToDo, start); if (error == ERR_EMPTY) break; start = false; qDebug("ReadTodo %d ", ++ccc); handler.readTodo( existingCal, &ToDo, &s); } error=GSM_TerminateConnection(&s); return true; } +void PhoneFormat::event2GSM( Event* ev, GSM_CalendarEntry*Note ) +{ -bool PhoneFormat::save( Calendar *calendar) +} +void PhoneFormat::todo2GSM( Todo* todo, GSM_ToDoEntry *gsm ) { #if 0 - QLabel status ( i18n("Processing/adding events ..."), 0 ); + QStringList list; + list.append( QString::number( todo->zaurusId() ) ); + list.append( todo->categories().join(",") ); + + if ( todo->hasStartDate() ) { + list.append( dtToString( todo->dtStart()) ); + } else + list.append( QString() ); + + if ( todo->hasDueDate() ) { + QTime tim; + if ( todo->doesFloat()) { + list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; + } else { + list.append( dtToString(todo->dtDue() ) ); + } + } else + list.append( QString() ); + + if ( todo->isCompleted() ) { + list.append( dtToString( todo->completed()) ); + list.append( "0" ); // yes 0 == completed + } else { + list.append( dtToString( todo->completed()) ); + list.append( "1" ); + } + list.append( QString::number( todo->priority() )); + if( ! todo->summary().isEmpty() ) + list.append( todo->summary() ); + else + list.append( "" ); + if (! todo->description().isEmpty() ) + list.append( todo->description() ); + else + list.append( "" ); + for(QStringList::Iterator it=list.begin(); + it!=list.end(); ++it){ + QString& s = (*it); + s.replace(QRegExp("\""), "\"\""); + if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ + s.prepend('\"'); + s.append('\"'); + } else if(s.isEmpty() && !s.isNull()){ + s = "\"\""; + } + } + return list.join(","); +#endif +} +bool PhoneFormat::save( Calendar *calendar) +{ + GSM_StateMachine s; + qDebug(" save "); + s.opened = false; + s.msg = NULL; + s.ConfigNum = 0; + QLabel status ( i18n("Writing data. Opening device ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 200; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Writing 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; + + int error=initDevice(&s); + qDebug("GSM Init %d (no error is %d)", error, ERR_NONE); + if ( error != ERR_NONE ) + return false; + GSM_Phone_Functions *Phone; + GSM_CalendarEntry Note; + bool start = true; + Phone=s.Phone.Functions; + bool gshutdown = false; QPtrList<Event> er = calendar->rawEvents(); Event* ev = er.first(); - QString 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 ( true /*ev->zaurusStat() != -2*/ ) { + if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { // event was changed during sync or is a new one + status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); - QString eString = getEventString( ev ); - if (/* ev->zaurusStat() == -3 */ true) { // 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*/true ) { // 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; - + event2GSM( ev, &Note ); + if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete + error = Phone->DeleteCalendar(&s, &Note); } - QTextStream ts( &file ); - ts.setCodec( QTextCodec::codecForName("utf8") ); - answer = ts.read(); - file.close(); - //qDebug("answer \n%s ", answer.latin1()); - getNumFromRecord( answer, ev ) ; + else if ( ev->getID(mProfileName).isEmpty() ) { // add new + // we have to do this later after deleting } 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; - + error = Phone->AddCalendar(&s, &Note); } } ev = er.next(); } - status.setText ( i18n("Changing events ...") ); + ev = er.first(); + // pending get empty slots + while ( ev ) { + if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && ev->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { + if ( ev->getID(mProfileName).isEmpty() ) { + status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); - //qDebug("changing... "); - if ( changeEnt ) { - QFile file( fileName ); - if (!file.open( IO_WriteOnly ) ) { - return false; - + int newID ;//= pending + ev->setID(mProfileName, QString::number( newID )); + event2GSM( ev, &Note ); + error = Phone->AddCalendar(&s, &Note); } - 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()); + ev = er.next(); } - - - changeString = tPrefix; - deleteString = tPrefix; - status.setText ( i18n("Processing todos ...") ); - qApp->processEvents(); + GSM_ToDoEntry ToDoEntry; QPtrList<Todo> tl = calendar->rawTodos(); Todo* to = tl.first(); - i = 0; + message = i18n("Processing todo # "); procCount = 0; while ( to ) { - if ( true /*to->zaurusStat() != -2 */) { + if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); - QString eString = getTodoString( to ); - if ( /*to->zaurusStat() == -3*/true ) { // 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 ( true /*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; - + todo2GSM( to, &ToDoEntry ); + if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete + error=Phone->DeleteToDo(&s,&ToDoEntry); } - QTextStream ts( &file ); - ts.setCodec( QTextCodec::codecForName("utf8") ); - answer = ts.read(); - file.close(); - //qDebug("answer \n%s ", answer.latin1()); - getNumFromRecord( answer, to ) ; - + else if ( to->getID("Sharp_DTM").isEmpty() ) { // add new + ; } 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; - + error=Phone->AddToDo(&s,&ToDoEntry); } } - 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 ...") ); + // pending get empty slots + to = tl.first(); + while ( to ) { + if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && to->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { + if ( to->getID(mProfileName).isEmpty() ) { + status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); - //qDebug("deleting... "); - if ( deleteEnt ) { - QFile file( fileName ); - if (!file.open( IO_WriteOnly ) ) { - return false; - + int newID ;//= pending + to->setID(mProfileName, QString::number( newID )); + todo2GSM( to, &ToDoEntry ); + error=Phone->AddToDo(&s,&ToDoEntry); } - 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()); } -#endif + to = tl.next(); + } return true; } QString PhoneFormat::dtToGSM( const QDateTime& dti, bool useTZ ) { QString datestr; QString timestr; int offset = KGlobal::locale()->localTimeOffset( dti ); QDateTime dt; if (useTZ) dt = dti.addSecs ( -(offset*60)); else dt = dti; if(dt.date().isValid()){ const QDate& date = dt.date(); datestr.sprintf("%04d%02d%02d", date.year(), date.month(), date.day()); } if(dt.time().isValid()){ const QTime& time = dt.time(); timestr.sprintf("T%02d%02d%02d", time.hour(), time.minute(), time.second()); } return datestr + timestr; } QString PhoneFormat::getEventString( Event* event ) { #if 0 QStringList list; list.append( QString::number(event->zaurusId() ) ); list.append( event->categories().join(",") ); if ( !event->summary().isEmpty() ) list.append( event->summary() ); else list.append("" ); if ( !event->location().isEmpty() ) list.append( event->location() ); else list.append("" ); if ( !event->description().isEmpty() ) list.append( event->description() ); else list.append( "" ); if ( event->doesFloat () ) { list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 list.append( "1" ); } else { list.append( dtToString( event->dtStart()) ); list.append( dtToString( event->dtEnd()) ); //6 list.append( "0" ); } bool noAlarm = true; if ( event->alarms().count() > 0 ) { Alarm * al = event->alarms().first(); if ( al->enabled() ) { noAlarm = false; list.append( "0" ); // yes, 0 == alarm list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); if ( al->type() == Alarm::Audio ) list.append( "1" ); // type audio else list.append( "0" ); // type silent } } if ( noAlarm ) { list.append( "1" ); // yes, 1 == no alarm list.append( "0" ); // no alarm offset list.append( "1" ); // type } // next is: 11 // next is: 11-16 are recurrence Recurrence* rec = event->recurrence(); bool writeEndDate = false; switch ( rec->doesRecur() ) { case Recurrence::rDaily: // 0 list.append( "0" ); list.append( QString::number( rec->frequency() ));//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; case Recurrence::rWeekly:// 1 list.append( "1" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); { int days = 0; QBitArray weekDays = rec->days(); int i; for( i = 1; i <= 7; ++i ) { if ( weekDays[i-1] ) { days += 1 << (i-1); } } list.append( QString::number( days ) ); } //pending weekdays writeEndDate = true; break; case Recurrence::rMonthlyPos:// 2 list.append( "2" ); list.append( QString::number( rec->frequency()) );//12 writeEndDate = true; { int count = 1; QPtrList<Recurrence::rMonthPos> rmp; rmp = rec->monthPositions(); if ( rmp.first()->negative ) count = 5 - rmp.first()->rPos - 1; else count = rmp.first()->rPos - 1; list.append( QString::number( count ) ); } list.append( "0" ); break; case Recurrence::rMonthlyDay:// 3 list.append( "3" ); list.append( QString::number( rec->frequency()) );//12 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(","); #endif return QString(); } QString PhoneFormat::getTodoString( Todo* todo ) { #if 0 QStringList list; list.append( QString::number( todo->zaurusId() ) ); list.append( todo->categories().join(",") ); if ( todo->hasStartDate() ) { list.append( dtToString( todo->dtStart()) ); } else list.append( QString() ); if ( todo->hasDueDate() ) { QTime tim; if ( todo->doesFloat()) { list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; } else { list.append( dtToString(todo->dtDue() ) ); } } else list.append( QString() ); if ( todo->isCompleted() ) { list.append( dtToString( todo->completed()) ); list.append( "0" ); // yes 0 == completed } else { list.append( dtToString( todo->completed()) ); list.append( "1" ); } list.append( QString::number( todo->priority() )); if( ! todo->summary().isEmpty() ) list.append( todo->summary() ); else list.append( "" ); if (! todo->description().isEmpty() ) list.append( todo->description() ); else list.append( "" ); for(QStringList::Iterator it=list.begin(); it!=list.end(); ++it){ QString& s = (*it); s.replace(QRegExp("\""), "\"\""); if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ s.prepend('\"'); s.append('\"'); } else if(s.isEmpty() && !s.isNull()){ s = "\"\""; } } return list.join(","); #endif return QString(); } QString PhoneFormat::toString( Calendar * ) { return QString::null; } bool PhoneFormat::fromString( Calendar *calendar, const QString & text) { return false; } diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h index 8d4e200..1472880 100644 --- a/libkcal/phoneformat.h +++ b/libkcal/phoneformat.h @@ -1,60 +1,63 @@ /* This file is part of libkcal. Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef PHONEFORMAT_H #define PHONEFORMAT_H #include <qstring.h> #include "scheduler.h" #include "calformat.h" extern "C" { #include "../gammu/emb/common/gammu.h" } - namespace KCal { /** This class implements the calendar format used by Phone. */ - + class Event; + class Todo; class PhoneFormat : public QObject { public: /** Create new iCalendar format. */ - PhoneFormat(); + PhoneFormat(QString profileName, QString device,QString connection, QString model); virtual ~PhoneFormat(); - bool load( Calendar * ,Calendar *, QString profileName, QString device,QString connection, QString model ); + bool load( Calendar * ,Calendar * ); bool save( Calendar * ); bool fromString( Calendar *, const QString & ); QString toString( Calendar * ); static ulong getCsum( const QStringList & ); private: + void event2GSM( Event* ev, GSM_CalendarEntry*Note ); + void todo2GSM( Todo* ev, GSM_ToDoEntry *ToDo ); + int initDevice(GSM_StateMachine *s); QString getEventString( Event* ); QString getTodoString( Todo* ); QString dtToGSM( const QDateTime& dt, bool useTZ = true ); - QString mProfileName; + QString mProfileName, mDevice, mConnection, mModel; }; } #endif |