summaryrefslogtreecommitdiffabout
path: root/libkcal/phoneformat.cpp
Side-by-side diff
Diffstat (limited to 'libkcal/phoneformat.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/phoneformat.cpp1359
1 files changed, 1359 insertions, 0 deletions
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,&note,refresh);
+ if (error == ERR_EMPTY) break;
+
+ Note = &note;
+//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;
+}