summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/phoneformat.cpp1427
-rw-r--r--libkcal/phoneformat.h8
2 files changed, 525 insertions, 910 deletions
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp
index fd6b6af..c97b43d 100644
--- a/libkcal/phoneformat.cpp
+++ b/libkcal/phoneformat.cpp
@@ -17,939 +17,938 @@
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21 21
22#include <qdatetime.h> 22#include <qdatetime.h>
23#include <qstring.h> 23#include <qstring.h>
24#include <qapplication.h> 24#include <qapplication.h>
25#include <qptrlist.h> 25#include <qptrlist.h>
26#include <qregexp.h> 26#include <qregexp.h>
27#include <qmessagebox.h> 27#include <qmessagebox.h>
28#include <qclipboard.h> 28#include <qclipboard.h>
29#include <qfile.h> 29#include <qfile.h>
30#include <qtextstream.h> 30#include <qtextstream.h>
31#include <qtextcodec.h> 31#include <qtextcodec.h>
32#include <qxml.h> 32#include <qxml.h>
33#include <qlabel.h> 33#include <qlabel.h>
34 34
35#include <kdebug.h> 35#include <kdebug.h>
36#include <klocale.h> 36#include <klocale.h>
37#include <kglobal.h> 37#include <kglobal.h>
38 38
39#include "calendar.h" 39#include "calendar.h"
40#include "alarm.h" 40#include "alarm.h"
41#include "recurrence.h" 41#include "recurrence.h"
42#include "calendarlocal.h" 42#include "calendarlocal.h"
43 43
44#include "phoneformat.h" 44#include "phoneformat.h"
45#include "syncdefines.h" 45#include "syncdefines.h"
46 46
47using namespace KCal; 47using namespace KCal;
48 48
49//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY 49//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY
50// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 50// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
51 51
52//ARSD silentalarm = 0 52//ARSD silentalarm = 0
53// 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly 53// 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly
54// 12 RFRQ 54// 12 RFRQ
55// 13 RPOS pos = 4. monday in month 55// 13 RPOS pos = 4. monday in month
56// 14 RDYS days: 1 mon/ 2 tue .. 64 sun 56// 14 RDYS days: 1 mon/ 2 tue .. 64 sun
57// 15 REND 0 = no end/ 1 = end 57// 15 REND 0 = no end/ 1 = end
58// 16 REDT rec end dt 58// 16 REDT rec end dt
59//ALSD 59//ALSD
60//ALED 60//ALED
61//MDAY 61//MDAY
62 62
63class PhoneParser : public QObject 63class PhoneParser : public QObject
64{ 64{
65 public: 65public:
66 PhoneParser( Calendar *calendar, QString profileName ) : mCalendar( calendar ), mProfileName ( profileName ) { 66 PhoneParser( Calendar *calendar, QString profileName ) : mCalendar( calendar ), mProfileName ( profileName ) {
67 oldCategories = 0; 67 ;
68 } 68 }
69 69 bool readTodo( Calendar *existingCalendar,GSM_ToDoEntry *ToDo, GSM_StateMachine* s)
70 bool startElement( Calendar *existingCalendar, GSM_CalendarEntry*Note, QString qName )
71 { 70 {
72 QStringList attList; 71
73 /* 72 int id = ToDo->Location;
74// pending csum 73 Todo *todo;
75 int i = 1; 74 todo = existingCalendar->todo( mProfileName ,QString::number( id ) );
76 bool skip = true; 75 if (todo )
77 int max = attList.count() -2; 76 todo = (Todo *)todo->clone();
78 while ( i < max ) { 77 else
79 if ( !attList[i].isEmpty() ) { 78 todo = new Todo;
80 skip = false; 79 todo->setID( mProfileName,QString::number( id ) );
80 todo->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL );
81 int priority;
82 switch (ToDo->Priority) {
83 case GSM_Priority_Low : priority = 1; break;
84 case GSM_Priority_Medium : priority = 3; break;
85 case GSM_Priority_High : priority = 5; break;
86 default :priority = 3 ;break;
87 }
88 todo->setPriority( priority );
89 GSM_Phone_Functions*Phone;
90 Phone=s->Phone.Functions;
91 int j;
92 GSM_DateTime* dtp;
93 bool alarm = false;
94 QDateTime alarmDt;
95 GSM_Category Category;
96 int error;
97 QString completedString = "no";
98 for (j=0;j<ToDo->EntriesNum;j++) {
99 switch (ToDo->Entries[j].EntryType) {
100 case TODO_END_DATETIME:
101 dtp = &ToDo->Entries[j].Date ;
102 todo->setDtDue (fromGSM ( dtp ));
103 break;
104 case TODO_COMPLETED:
105 if ( ToDo->Entries[j].Number == 1 ) {
106 todo->setCompleted( true );
107 completedString = "yes";
108 }
109 else {
110 todo->setCompleted( false );
111 }
112 break;
113 case TODO_ALARM_DATETIME:
114 dtp = &ToDo->Entries[j].Date ;
115 alarm = true;
116 alarmDt = fromGSM ( dtp );
117 break;
118 case TODO_SILENT_ALARM_DATETIME:
119 dtp = &ToDo->Entries[j].Date ;
120 alarm = true;
121 alarmDt = fromGSM ( dtp );
122 break;
123 case TODO_TEXT:
124 todo->setSummary( QString ( (const char*) ToDo->Entries[j].Text ));
125 break;
126 case TODO_PRIVATE:
127 if ( ToDo->Entries[j].Number == 1 )
128 todo->setSecrecy( Incidence::SecrecyPrivate );
129 else
130 todo->setSecrecy( Incidence::SecrecyPublic );
131 break;
132 case TODO_CATEGORY:
133 Category.Location = ToDo->Entries[j].Number;
134 Category.Type = Category_ToDo;
135 error=Phone->GetCategory(s, &Category);
136 if (error == ERR_NONE) {
137 QStringList cat = todo->categories();
138 QString nCat = QString ( (const char*)Category.Name );
139 if ( !nCat.isEmpty() )
140 if ( !cat.contains( nCat )) {
141 cat << nCat;
142 todo->setCategories( cat );
143 }
144 }
145 break;
146 case TODO_CONTACTID:
147#if 0
148 // not supported
149 entry.Location = ToDo->Entries[j].Number;
150 entry.MemoryType = MEM_ME;
151 error=Phone->GetMemory(s, &entry);
152 if (error == ERR_NONE) {
153 name = GSM_PhonebookGetEntryName(&entry);
154 if (name != NULL) {
155 printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), ToDo->Entries[j].Number);
156 } else {
157 printmsg("Contact ID : %d\n",ToDo->Entries[j].Number);
158 }
159 } else {
160 printmsg("Contact : %d\n",ToDo->Entries[j].Number);
161 }
162#endif
81 break; 163 break;
82 } 164 case TODO_PHONE:
83 ++i ; 165#if 0
166 // not supported
167 printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(ToDo->Entries[j].Text));
168#endif
169 break;
170 }
84 } 171 }
85 if ( skip ) 172 QString alarmString = "";
86 return false; 173 // strange 0 semms to mean: alarm enabled
87 ulong cSum = PhoneFormat::getCsum(attList ); 174 if ( alarm ) {
88 */ 175 Alarm *alarm;
89 if ( qName == "Event" ) { 176 if ( todo->alarms().count() > 0 )
90 int id = Note->Location; 177 alarm = todo->alarms().first();
91 Event *event; 178 else {
92 event = existingCalendar->event( mProfileName ,QString::number( id ) ); 179 alarm = new Alarm( todo );
93 if ( event ) 180 todo->addAlarm( alarm );
94 event = (Event*)event->clone(); 181 }
95 else 182 alarm->setType( Alarm::Audio );
96 event = new Event; 183 alarm->setEnabled( true );
97 event->setID( mProfileName, attList[0] ); 184 int alarmOffset = alarmDt.secsTo( todo->dtStart() );
98 // pending event->setCsum( "Sharp_DTM", QString::number( cSum )); 185 alarm->setStartOffset( alarmOffset );
99 event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); 186 alarmString = QString::number( alarmOffset );
100 187 }
101 188 // csum *****************************************
102 int i = 0; 189 QStringList attList;
103 bool repeating = false; 190 uint cSum;
104 int repeat_dayofweek = -1; 191 if ( todo->hasDueDate() )
105 int repeat_day = -1; 192 attList << dtToString ( todo->dtDue() );
106 int repeat_weekofmonth = -1; 193 attList << QString::number( id );
107 int repeat_month = -1; 194 attList << todo->summary();
108 int repeat_frequency = -1; 195 attList << completedString;
109 GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; 196 attList << alarmString;
110 GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; 197 attList << todo->categoriesStr();
111 GSM_DateTime* dtp; 198 attList << todo->secrecyStr();
112 bool alarm = false; 199 cSum = PhoneFormat::getCsum(attList );
113 QDateTime alarmDt; 200 todo->setCsum( mProfileName, QString::number( cSum ));
114 repeat_startdate.Day= 0; 201 mCalendar->addTodo( todo);
115 repeat_stopdate.Day = 0;
116 for (i=0;i<Note->EntriesNum;i++) {
117 202
118 qDebug(" for "); 203 return true;
119 switch (Note->Entries[i].EntryType) { 204 }
120 case CAL_START_DATETIME: 205 bool readEvent( Calendar *existingCalendar, GSM_CalendarEntry*Note)
121 dtp = &Note->Entries[i].Date ; 206 {
122 if ( dtp->Hour > 24 ) { 207
123 event->setFloats( true ); 208 int id = Note->Location;
124 event->setDtStart( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); 209 Event *event;
125 } else { 210 event = existingCalendar->event( mProfileName ,QString::number( id ) );
126 event->setDtStart (fromGSM ( dtp )); 211 if ( event )
212 event = (Event*)event->clone();
213 else
214 event = new Event;
215 event->setID( mProfileName,QString::number( id ) );
216 event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL );
217
218
219 int i = 0;
220 bool repeating = false;
221 int repeat_dayofweek = -1;
222 int repeat_day = -1;
223 int repeat_weekofmonth = -1;
224 int repeat_month = -1;
225 int repeat_frequency = -1;
226 int rec_type = -1;
227 GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0};
228 GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0};
229 GSM_DateTime* dtp;
230 bool alarm = false;
231 QDateTime alarmDt;
232 repeat_startdate.Day= 0;
233 repeat_stopdate.Day = 0;
234 for (i=0;i<Note->EntriesNum;i++) {
235
236 qDebug(" for ");
237 switch (Note->Entries[i].EntryType) {
238 case CAL_START_DATETIME:
239 dtp = &Note->Entries[i].Date ;
240 if ( dtp->Hour > 24 ) {
241 event->setFloats( true );
242 event->setDtStart( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 )));
243 } else {
244 event->setDtStart (fromGSM ( dtp ));
127 245
128 } 246 }
129 break; 247 break;
130 case CAL_END_DATETIME: 248 case CAL_END_DATETIME:
131 dtp = &Note->Entries[i].Date ; 249 dtp = &Note->Entries[i].Date ;
132 if ( dtp->Hour > 24 ) { 250 if ( dtp->Hour > 24 ) {
133 event->setFloats( true ); 251 event->setFloats( true );
134 event->setDtEnd( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); 252 event->setDtEnd( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 )));
135 } else { 253 } else {
136 event->setDtEnd (fromGSM ( dtp )); 254 event->setDtEnd (fromGSM ( dtp ));
137 } 255 }
138 break; 256 break;
139 case CAL_ALARM_DATETIME: 257 case CAL_ALARM_DATETIME:
140 dtp = &Note->Entries[i].Date ; 258 dtp = &Note->Entries[i].Date ;
141 alarm = true; 259 alarm = true;
142 alarmDt = fromGSM ( dtp ); 260 alarmDt = fromGSM ( dtp );
143 break; 261 break;
144 case CAL_SILENT_ALARM_DATETIME: 262 case CAL_SILENT_ALARM_DATETIME:
145 dtp = &Note->Entries[i].Date ; 263 dtp = &Note->Entries[i].Date ;
146 alarm = true; 264 alarm = true;
147 alarmDt = fromGSM ( dtp ); 265 alarmDt = fromGSM ( dtp );
148 break; 266 break;
149 case CAL_RECURRANCE: 267 case CAL_RECURRANCE:
150 //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" ); 268 rec_type = Note->Entries[i].Number;
151 break; 269 //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" );
152 case CAL_TEXT: 270 break;
153 event->setSummary( QString ( (const char*) Note->Entries[i].Text )); 271 case CAL_TEXT:
154 break; 272 event->setSummary( QString ( (const char*) Note->Entries[i].Text ));
155 case CAL_LOCATION: 273 break;
156 event->setLocation(QString ((const char*) Note->Entries[i].Text )); 274 case CAL_LOCATION:
157 break; 275 event->setLocation(QString ((const char*) Note->Entries[i].Text ));
158 case CAL_PHONE: 276 break;
159 //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); 277 case CAL_PHONE:
160 break; 278 //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text));
161 case CAL_PRIVATE: 279 break;
162 //printmsg("Private : %s\n",Note->Entries[i].Number == 1 ? "Yes" : "No"); 280 case CAL_PRIVATE:
163 break; 281 if ( Note->Entries[i].Number == 1 )
164 case CAL_CONTACTID: 282 event->setSecrecy( Incidence::SecrecyPrivate );
283 else
284 event->setSecrecy( Incidence::SecrecyPublic );
285
286 break;
287 case CAL_CONTACTID:
165#if 0 288#if 0
166 entry.Location = Note->Entries[i].Number; 289 entry.Location = Note->Entries[i].Number;
167 entry.MemoryType = MEM_ME; 290 entry.MemoryType = MEM_ME;
168 error=Phone->GetMemory(&s, &entry); 291 error=Phone->GetMemory(&s, &entry);
169 if (error == ERR_NONE) { 292 if (error == ERR_NONE) {
170 name = GSM_PhonebookGetEntryName(&entry); 293 name = GSM_PhonebookGetEntryName(&entry);
171 if (name != NULL) { 294 if (name != NULL) {
172 //printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number); 295 //printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number);
173 } else {
174 //printmsg("Contact ID : %d\n",Note->Entries[i].Number);
175 }
176 } else { 296 } else {
177 //printmsg("Contact ID : %d\n",Note->Entries[i].Number); 297 //printmsg("Contact ID : %d\n",Note->Entries[i].Number);
178 } 298 }
179#endif 299 } else {
180 break; 300 //printmsg("Contact ID : %d\n",Note->Entries[i].Number);
181 case CAL_REPEAT_DAYOFWEEK:
182 repeat_dayofweek = Note->Entries[i].Number;
183 repeating = true;
184 break;
185 case CAL_REPEAT_DAY:
186 repeat_day = Note->Entries[i].Number;
187 repeating = true;
188 break;
189 case CAL_REPEAT_WEEKOFMONTH:
190 repeat_weekofmonth = Note->Entries[i].Number;
191 repeating = true;
192 break;
193 case CAL_REPEAT_MONTH:
194 repeat_month = Note->Entries[i].Number;
195 repeating = true;
196 break;
197 case CAL_REPEAT_FREQUENCY:
198 repeat_frequency = Note->Entries[i].Number;
199 repeating = true;
200 break;
201 case CAL_REPEAT_STARTDATE:
202 repeat_startdate = Note->Entries[i].Date;
203 repeating = true;
204 break;
205 case CAL_REPEAT_STOPDATE:
206 repeat_stopdate = Note->Entries[i].Date;
207 repeating = true;
208 break;
209 } 301 }
302#endif
303 break;
304 case CAL_REPEAT_DAYOFWEEK:
305 repeat_dayofweek = Note->Entries[i].Number;
306 repeating = true;
307 break;
308 case CAL_REPEAT_DAY:
309 repeat_day = Note->Entries[i].Number;
310 repeating = true;
311 break;
312 case CAL_REPEAT_WEEKOFMONTH:
313 repeat_weekofmonth = Note->Entries[i].Number;
314 repeating = true;
315 break;
316 case CAL_REPEAT_MONTH:
317 repeat_month = Note->Entries[i].Number;
318 repeating = true;
319 break;
320 case CAL_REPEAT_FREQUENCY:
321 repeat_frequency = Note->Entries[i].Number;
322 repeating = true;
323 break;
324 case CAL_REPEAT_STARTDATE:
325 repeat_startdate = Note->Entries[i].Date;
326 repeating = true;
327 break;
328 case CAL_REPEAT_STOPDATE:
329 repeat_stopdate = Note->Entries[i].Date;
330 repeating = true;
331 break;
210 } 332 }
333 }
211#if 0 334#if 0
212 event->setDescription( attList[4] ); 335 event->setDescription( attList[4] );
213 bool repeating = false; 336 bool repeating = false;
214 int repeat_dayofweek = -1; 337 int repeat_dayofweek = -1;
215 int repeat_day = -1; 338 int repeat_day = -1;
216 int repeat_weekofmonth = -1; 339 int repeat_weekofmonth = -1;
217 int repeat_month = -1; 340 int repeat_month = -1;
218 int repeat_frequency = -1; 341 int repeat_frequency = -1;
219 GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; 342 GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0};
220 GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; 343 GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0};
221 344
222#endif 345#endif
223 346
224 QString rtype = attList[11]; 347 QString recurString = "no";
225 if ( repeating ) { 348 if ( repeating ) {
226 int rtype = 0; 349 recurString = "y";
227 // qDebug("recurs "); 350 if ( repeat_dayofweek >= 0 )
228 QDate startDate, endDate; 351 recurString += "dow" + QString::number (repeat_dayofweek);
229 if ( repeat_startdate.Day > 0 ) 352 if ( repeat_day >= 0 )
230 startDate = datefromGSM ( &repeat_startdate ); 353 recurString += "d" + QString::number (repeat_day);
231 else 354 if ( repeat_weekofmonth >= 0 )
232 startDate = event->dtStart().date(); 355 recurString += "w" + QString::number (repeat_weekofmonth);
233 int freq = repeat_frequency; 356 if ( repeat_month >= 0 )
234 bool hasEndDate = false; 357 recurString += "m" + QString::number ( repeat_month );
235 if ( repeat_stopdate.Day > 0 ) { 358 if ( repeat_frequency >= 0 )
236 endDate = datefromGSM ( &repeat_stopdate ); 359 recurString += "f" + QString::number (repeat_frequency );
237 hasEndDate = true; 360
238 } 361 int rtype = 0;
362 // qDebug("recurs ");
363 QDate startDate, endDate;
364 if ( repeat_startdate.Day > 0 )
365 startDate = datefromGSM ( &repeat_startdate );
366 else
367 startDate = event->dtStart().date();
368 int freq = repeat_frequency;
369 bool hasEndDate = false;
370 if ( repeat_stopdate.Day > 0 ) {
371 endDate = datefromGSM ( &repeat_stopdate );
372 hasEndDate = true;
373 }
239 374
240 uint weekDaysNum = repeat_dayofweek ; 375 uint weekDaysNum = repeat_dayofweek ;
241 376
242 QBitArray weekDays( 7 ); 377 QBitArray weekDays( 7 );
243 int i; 378 int i;
244 int bb = 1; 379 int bb = 1;
245 for( i = 1; i <= 7; ++i ) { 380 for( i = 1; i <= 7; ++i ) {
246 weekDays.setBit( i - 1, ( bb & weekDaysNum )); 381 weekDays.setBit( i - 1, ( bb & weekDaysNum ));
247 bb = 2 << (i-1); 382 bb = 2 << (i-1);
248 //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) ); 383 //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) );
249 }
250 // qDebug("next ");
251 int pos = 0;
252 Recurrence *r = event->recurrence();
253 /*
254 0 daily;
255 1 weekly;x
256 2 monthpos;x
257 3 monthlyday;
258 4 rYearlyMont
259 */
260 int dayOfWeek = startDate.dayOfWeek();
261 if ( repeat_weekofmonth >= 0 ) {
262 rtype = 2;
263 pos = repeat_weekofmonth;
264 if ( repeat_dayofweek >= 0 )
265 dayOfWeek = repeat_dayofweek;
266 } else if ( repeat_dayofweek >= 0 ) {
267 rtype = 1;
268 } if ( repeat_dayofweek >= 0 ) {
269 rtype = 1;
270 }
271
272 if ( rtype == 0 ) {
273 if ( hasEndDate ) r->setDaily( freq, endDate );
274 else r->setDaily( freq, -1 );
275 } else if ( rtype == 1 ) {
276 if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate );
277 else r->setWeekly( freq, weekDays, -1 );
278 } else if ( rtype == 3 ) {
279 if ( hasEndDate )
280 r->setMonthly( Recurrence::rMonthlyDay, freq, endDate );
281 else
282 r->setMonthly( Recurrence::rMonthlyDay, freq, -1 );
283 r->addMonthlyDay( startDate.day() );
284 } else if ( rtype == 2 ) {
285 if ( hasEndDate )
286 r->setMonthly( Recurrence::rMonthlyPos, freq, endDate );
287 else
288 r->setMonthly( Recurrence::rMonthlyPos, freq, -1 );
289 QBitArray days( 7 );
290 days.fill( false );
291 days.setBit( dayOfWeek - 1 );
292 r->addMonthlyPos( pos, days );
293 } else if ( rtype == 4 ) {
294 if ( hasEndDate )
295 r->setYearly( Recurrence::rYearlyMonth, freq, endDate );
296 else
297 r->setYearly( Recurrence::rYearlyMonth, freq, -1 );
298 r->addYearlyNum( startDate.month() );
299 }
300 } else {
301 event->recurrence()->unsetRecurs();
302 } 384 }
303 385 // qDebug("next ");
304 QString categoryList = attList[1] ; 386 int pos = 0;
305 event->setCategories( lookupCategories( categoryList ) ); 387 Recurrence *r = event->recurrence();
306 388 /*
307 // strange 0 semms to mean: alarm enabled 389 0 daily;
308 if ( alarm ) { 390 1 weekly;x
309 Alarm *alarm; 391 2 monthpos;x
310 if ( event->alarms().count() > 0 ) 392 3 monthlyday;
311 alarm = event->alarms().first(); 393 4 rYearlyMont
312 else { 394 bool repeating = false;
313 alarm = new Alarm( event ); 395 int repeat_dayofweek = -1;
314 event->addAlarm( alarm ); 396 int repeat_day = -1;
315 } 397 int repeat_weekofmonth = -1;
316 alarm->setType( Alarm::Audio ); 398 int repeat_month = -1;
317 alarm->setEnabled( true ); 399 int repeat_frequency = -1;
318 int alarmOffset = alarmDt.secsTo( event->dtStart() ); 400 */
319 alarm->setStartOffset( alarmOffset ); 401 int dayOfWeek = startDate.dayOfWeek();
402 if ( repeat_weekofmonth >= 0 ) {
403 rtype = 2;
404 pos = repeat_weekofmonth;
405 if ( repeat_dayofweek >= 0 )
406 dayOfWeek = repeat_dayofweek;
407 } else if ( repeat_dayofweek >= 0 ) {
408 rtype = 1;
409 } if ( repeat_dayofweek >= 0 ) {
410 rtype = 1;
320 } 411 }
321 mCalendar->addEvent( event);
322 } else if ( qName == "Todo" ) {
323#if 0
324 Todo *todo;
325 412
326 todo = existingCalendar->todo( attList[0] ); 413 if ( rtype == 0 ) {
327 if (todo ) 414 if ( hasEndDate ) r->setDaily( freq, endDate );
328 todo = (Todo*)todo->clone(); 415 else r->setDaily( freq, -1 );
329 else 416 } else if ( rtype == 1 ) {
330 todo = new Todo; 417 if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate );
331 418 else r->setWeekly( freq, weekDays, -1 );
332//CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1 419 } else if ( rtype == 3 ) {
333// 0 1 2 3 4 5 6 7 8 420 if ( hasEndDate )
334//1,,,,,1,4,Loch zumachen,"" 421 r->setMonthly( Recurrence::rMonthlyDay, freq, endDate );
335//3,Privat,20040317T000000,20040318T000000,20040319T000000,0,5,Call bbb,"notes123 bbb gggg ""bb "" " 422 else
336//2,"Familie,Freunde,Holiday",20040318T000000,20040324T000000,20040317T000000,1,2,tod2,notes 423 r->setMonthly( Recurrence::rMonthlyDay, freq, -1 );
337 424 r->addMonthlyDay( startDate.day() );
338 //todo->setZaurusId( attList[0] ); 425 } else if ( rtype == 2 ) {
339 //todo->setZaurusUid( cSum ); 426 if ( hasEndDate )
340 //todo->setZaurusStat( -2 ); 427 r->setMonthly( Recurrence::rMonthlyPos, freq, endDate );
341 428 else
342 todo->setSummary( attList[7] ); 429 r->setMonthly( Recurrence::rMonthlyPos, freq, -1 );
343 todo->setDescription( attList[8]); 430 QBitArray days( 7 );
344 431 days.fill( false );
345 int priority = attList[6].toInt(); 432 days.setBit( dayOfWeek - 1 );
346 if ( priority == 0 ) priority = 3; 433 r->addMonthlyPos( pos, days );
347 todo->setPriority( priority ); 434 } else if ( rtype == 4 ) {
348 435 if ( hasEndDate )
349 QString categoryList = attList[1]; 436 r->setYearly( Recurrence::rYearlyMonth, freq, endDate );
350 todo->setCategories( lookupCategories( categoryList ) ); 437 else
351 438 r->setYearly( Recurrence::rYearlyMonth, freq, -1 );
352 439 r->addYearlyNum( startDate.month() );
353
354 QString hasDateStr = attList[3]; // due
355 if ( !hasDateStr.isEmpty() ) {
356 if ( hasDateStr.right(6) == "000000" ) {
357 todo->setDtDue( QDateTime(fromString( hasDateStr, false ).date(), QTime(0,0,0 )) );
358 todo->setFloats( true );
359 }
360 else {
361 todo->setDtDue( fromString( hasDateStr ) );
362 todo->setFloats( false );
363 }
364
365 todo->setHasDueDate( true );
366 }
367 hasDateStr = attList[2];//start
368 if ( !hasDateStr.isEmpty() ) {
369
370 todo->setDtStart( fromString( hasDateStr ) );
371 todo->setHasStartDate( true);
372 } else
373 todo->setHasStartDate( false );
374 hasDateStr = attList[4];//completed
375 if ( !hasDateStr.isEmpty() ) {
376 todo->setCompleted(fromString( hasDateStr ) );
377 } 440 }
378 QString completedStr = attList[5]; 441 } else {
379 if ( completedStr == "0" ) 442 event->recurrence()->unsetRecurs();
380 todo->setCompleted( true ); 443 }
381 else
382 todo->setCompleted( false );
383 mCalendar->addTodo( todo );
384#endif
385 444
386 } else if ( qName == "Category" ) { 445 QStringList categoryList;
387 /* 446 categoryList << getCategory( Note );
388 QString id = attributes.value( "id" ); 447 event->setCategories( categoryList );
389 QString name = attributes.value( "name" ); 448 QString alarmString = "";
390 setCategory( id, name ); 449 // strange 0 semms to mean: alarm enabled
391 */ 450 if ( alarm ) {
451 Alarm *alarm;
452 if ( event->alarms().count() > 0 )
453 alarm = event->alarms().first();
454 else {
455 alarm = new Alarm( event );
456 event->addAlarm( alarm );
457 }
458 alarm->setType( Alarm::Audio );
459 alarm->setEnabled( true );
460 int alarmOffset = alarmDt.secsTo( event->dtStart() );
461 alarm->setStartOffset( alarmOffset );
462 alarmString = QString::number( alarmOffset );
392 } 463 }
393 //qDebug("end "); 464 // csum *****************************************
465 QStringList attList;
466 uint cSum;
467 attList << dtToString ( event->dtStart() );
468 attList << dtToString ( event->dtEnd() );
469 attList << QString::number( id );
470 attList << event->summary();
471 attList << event->location();
472 attList << alarmString;
473 attList << recurString;
474 attList << event->categoriesStr();
475 attList << event->secrecyStr();
476 cSum = PhoneFormat::getCsum(attList );
477 event->setCsum( mProfileName, QString::number( cSum ));
478 mCalendar->addEvent( event);
479
394 return true; 480 return true;
395 } 481 }
396 482
397 483
398 void setCategoriesList ( QStringList * c )
399 {
400 oldCategories = c;
401 }
402
403 QDateTime fromGSM ( GSM_DateTime*dtp, bool useTz = true ) { 484 QDateTime fromGSM ( GSM_DateTime*dtp, bool useTz = true ) {
404 QDateTime dt; 485 QDateTime dt;
405 int y,m,t,h,min,sec; 486 int y,m,t,h,min,sec;
406 y = dtp->Year; 487 y = dtp->Year;
407 m = dtp->Month; 488 m = dtp->Month;
408 t = dtp->Day; 489 t = dtp->Day;
409 h = dtp->Hour; 490 h = dtp->Hour;
410 min = dtp->Minute; 491 min = dtp->Minute;
411 sec = dtp->Second; 492 sec = dtp->Second;
412 dt = QDateTime(QDate(y,m,t), QTime(h,min,sec)); 493 dt = QDateTime(QDate(y,m,t), QTime(h,min,sec));
413 // dtp->Timezone: offset in hours 494 // dtp->Timezone: offset in hours
414 int offset = KGlobal::locale()->localTimeOffset( dt ); 495 int offset = KGlobal::locale()->localTimeOffset( dt );
415 if ( useTz ) 496 if ( useTz )
416 dt = dt.addSecs ( offset*60); 497 dt = dt.addSecs ( offset*60);
417 return dt; 498 return dt;
418 499
419 }
420 QDate datefromGSM ( GSM_DateTime*dtp ) {
421 return QDate ( dtp->Year, dtp->Month, dtp->Day );
422 }
423 protected:
424 QDateTime toDateTime( const QString &value )
425 {
426 QDateTime dt;
427 dt.setTime_t( value.toUInt() );
428
429 return dt;
430 } 500 }
431 501
432 QStringList lookupCategories( const QString &categoryList ) 502 QString dtToString( const QDateTime& dti, bool useTZ = false )
433 { 503 {
434 QStringList categoryIds = QStringList::split( ";", categoryList ); 504 QString datestr;
435 QStringList categories; 505 QString timestr;
436 QStringList::ConstIterator it; 506 int offset = KGlobal::locale()->localTimeOffset( dti );
437 for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) { 507 QDateTime dt;
438 QString cate = category( *it ); 508 if (useTZ)
439 if ( oldCategories ) { 509 dt = dti.addSecs ( -(offset*60));
440 if ( ! oldCategories->contains( cate ) ) 510 else
441 oldCategories->append( cate ); 511 dt = dti;
442 } 512 if(dt.date().isValid()){
443 categories.append(cate ); 513 const QDate& date = dt.date();
444 } 514 datestr.sprintf("%04d%02d%02d",
445 return categories; 515 date.year(), date.month(), date.day());
516 }
517 if(dt.time().isValid()){
518 const QTime& time = dt.time();
519 timestr.sprintf("T%02d%02d%02d",
520 time.hour(), time.minute(), time.second());
521 }
522 return datestr + timestr;
446 } 523 }
447 524 QDate datefromGSM ( GSM_DateTime*dtp ) {
448 private: 525 return QDate ( dtp->Year, dtp->Month, dtp->Day );
449 QString mProfileName ;
450 Calendar *mCalendar;
451 QStringList * oldCategories;
452 static QString category( const QString &id )
453 {
454 QMap<QString,QString>::ConstIterator it = mCategoriesMap.find( id );
455 if ( it == mCategoriesMap.end() ) return id;
456 else return *it;
457 } 526 }
458 527 QString getCategory( GSM_CalendarEntry*Note)
459 static void setCategory( const QString &id, const QString &name )
460 { 528 {
461 mCategoriesMap.insert( id, name ); 529 QString CATEGORY;
530 switch (Note->Type) {
531 case GSM_CAL_REMINDER : CATEGORY = QString("Reminder"); break;
532 case GSM_CAL_CALL : CATEGORY = QString("Call"); break;
533 case GSM_CAL_MEETING : CATEGORY = QString("Meeting"); break;
534 case GSM_CAL_BIRTHDAY : CATEGORY = QString("Birthday"); break;
535 case GSM_CAL_MEMO : CATEGORY = QString("Memo"); break;
536 case GSM_CAL_TRAVEL : CATEGORY = QString("Travel"); break;
537 case GSM_CAL_VACATION : CATEGORY = QString("Vacation"); break;
538 case GSM_CAL_ALARM : CATEGORY = QString("Alarm"); break;
539 case GSM_CAL_DAILY_ALARM : CATEGORY = QString("Daily alarm"); break;
540 case GSM_CAL_T_ATHL : CATEGORY = QString("Training/Athletism"); break;
541 case GSM_CAL_T_BALL : CATEGORY = QString("Training/Ball Games"); break;
542 case GSM_CAL_T_CYCL : CATEGORY = QString("Training/Cycling"); break;
543 case GSM_CAL_T_BUDO : CATEGORY = QString("Training/Budo"); break;
544 case GSM_CAL_T_DANC : CATEGORY = QString("Training/Dance"); break;
545 case GSM_CAL_T_EXTR : CATEGORY = QString("Training/Extreme Sports"); break;
546 case GSM_CAL_T_FOOT : CATEGORY = QString("Training/Football"); break;
547 case GSM_CAL_T_GOLF : CATEGORY = QString("Training/Golf"); break;
548 case GSM_CAL_T_GYM : CATEGORY = QString("Training/Gym"); break;
549 case GSM_CAL_T_HORS : CATEGORY = QString("Training/Horse Races"); break;
550 case GSM_CAL_T_HOCK : CATEGORY = QString("Training/Hockey"); break;
551 case GSM_CAL_T_RACE : CATEGORY = QString("Training/Races"); break;
552 case GSM_CAL_T_RUGB : CATEGORY = QString("Training/Rugby"); break;
553 case GSM_CAL_T_SAIL : CATEGORY = QString("Training/Sailing"); break;
554 case GSM_CAL_T_STRE : CATEGORY = QString("Training/Street Games"); break;
555 case GSM_CAL_T_SWIM : CATEGORY = QString("Training/Swimming"); break;
556 case GSM_CAL_T_TENN : CATEGORY = QString("Training/Tennis"); break;
557 case GSM_CAL_T_TRAV : CATEGORY = QString("Training/Travels"); break;
558 case GSM_CAL_T_WINT : CATEGORY = QString("Training/Winter Games"); break;
559 default : CATEGORY = QString("");
560 }
561
562 return CATEGORY;
462 } 563 }
463 564
464 static QMap<QString,QString> mCategoriesMap; 565protected:
566private:
567 Calendar *mCalendar;
568 QString mProfileName ;
465}; 569};
466 570
467QMap<QString,QString> PhoneParser::mCategoriesMap;
468 571
469PhoneFormat::PhoneFormat() 572PhoneFormat::PhoneFormat()
470{ 573{
471 mCategories = 0; 574 ;
472} 575}
473 576
474PhoneFormat::~PhoneFormat() 577PhoneFormat::~PhoneFormat()
475{ 578{
476} 579}
477ulong PhoneFormat::getCsum( const QStringList & attList) 580ulong PhoneFormat::getCsum( const QStringList & attList)
478{ 581{
479 int max = attList.count() -1; 582 int max = attList.count() -1;
480 ulong cSum = 0; 583 ulong cSum = 0;
481 int j,k,i; 584 int j,k,i;
482 int add; 585 int add;
483 for ( i = 1; i < max ; ++i ) { 586 for ( i = 1; i < max ; ++i ) {
484 QString s = attList[i]; 587 QString s = attList[i];
485 if ( ! s.isEmpty() ){ 588 if ( ! s.isEmpty() ){
486 j = s.length(); 589 j = s.length();
487 for ( k = 0; k < j; ++k ) { 590 for ( k = 0; k < j; ++k ) {
488 int mul = k +1; 591 int mul = k +1;
489 add = s[k].unicode (); 592 add = s[k].unicode ();
490 if ( k < 16 ) 593 if ( k < 16 )
491 mul = mul * mul; 594 mul = mul * mul;
492 add = add * mul *i*i*i; 595 add = add * mul *i*i*i;
493 cSum += add; 596 cSum += add;
494 } 597 }
495 } 598 }
496 } 599 }
497 return cSum; 600 return cSum;
498 601
499} 602}
500//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum); 603//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum);
501#include <stdlib.h> 604#include <stdlib.h>
502#define DEBUGMODE false 605#define DEBUGMODE false
503bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal ,QString profileName, QString device,QString connection, QString model ) 606bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal ,QString profileName, QString device,QString connection, QString model )
504{ 607{
505 mProfileName = profileName; 608 mProfileName = profileName;
506 GSM_StateMachines; 609 GSM_StateMachines;
507 qDebug(" load "); 610 qDebug(" load ");
508 s.opened = false; 611 s.opened = false;
509 s.msg = NULL; 612 s.msg = NULL;
510 s.ConfigNum = 0; 613 s.ConfigNum = 0;
511 static char*cp; 614 static char*cp;
512 static INI_Section *cfg = NULL; 615 static INI_Section *cfg = NULL;
513 cfg=GSM_FindGammuRC(); 616 cfg=GSM_FindGammuRC();
514 int i; 617 int i;
515 for (i = 0; i <= MAX_CONFIG_NUM; i++) { 618 for (i = 0; i <= MAX_CONFIG_NUM; i++) {
516 if (cfg!=NULL) { 619 if (cfg!=NULL) {
517 cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false); 620 cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false);
518 if (cp) di.coding = cp; 621 if (cp) di.coding = cp;
519 622
520 s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false); 623 s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false);
521 if (s.Config[i].Localize) { 624 if (s.Config[i].Localize) {
522 s.msg=INI_ReadFile(s.Config[i].Localize, true); 625 s.msg=INI_ReadFile(s.Config[i].Localize, true);
523 } else { 626 } else {
524#if !defined(WIN32) && defined(LOCALE_PATH) 627#if !defined(WIN32) && defined(LOCALE_PATH)
525 locale = setlocale(LC_MESSAGES, NULL); 628 locale = setlocale(LC_MESSAGES, NULL);
526 if (locale != NULL) { 629 if (locale != NULL) {
527 snprintf(locale_file, 200, "%s/gammu_%c%c.txt", 630 snprintf(locale_file, 200, "%s/gammu_%c%c.txt",
528 LOCALE_PATH, 631 LOCALE_PATH,
529 tolower(locale[0]), 632 tolower(locale[0]),
530 tolower(locale[1])); 633 tolower(locale[1]));
531 s.msg = INI_ReadFile(locale_file, true); 634 s.msg = INI_ReadFile(locale_file, true);
532 } 635 }
533#endif 636#endif
534 } 637 }
535 } 638 }
536 639
537 /* Wanted user specific configuration? */ 640 /* Wanted user specific configuration? */
538 641
539 if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; 642 if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break;
540 643
541 s.ConfigNum++; 644 s.ConfigNum++;
542 645
543 /* We want to use only one file descriptor for global and state machine debug output */ 646 /* We want to use only one file descriptor for global and state machine debug output */
544 s.Config[i].UseGlobalDebugFile = true; 647 s.Config[i].UseGlobalDebugFile = true;
545 648
546 649
547 650
548 /* We wanted to read just user specified configuration. */ 651 /* We wanted to read just user specified configuration. */
549 {break;} 652 {break;}
550 } 653 }
551 654
552
553
554
555 int error=GSM_InitConnection(&s,3); 655 int error=GSM_InitConnection(&s,3);
556
557
558 qDebug(" init %d %d", error, ERR_NONE); 656 qDebug(" init %d %d", error, ERR_NONE);
559 if ( error != ERR_NONE ) 657 if ( error != ERR_NONE )
560 return false; 658 return false;
561 // fromString2Cal( calendar, existngCal, &s, "Event" ); 659 // fromString2Cal( calendar, existngCal, &s, "Event" );
562 GSM_Phone_Functions*Phone; 660 GSM_Phone_Functions*Phone;
563 GSM_CalendarEntrynote; 661 GSM_CalendarEntrynote;
564 bool refresh= true; 662 bool refresh= true;
565 Phone=s.Phone.Functions; 663 Phone=s.Phone.Functions;
566 bool gshutdown = false; 664 bool gshutdown = false;
567 PhoneParser handler( calendar, profileName ); 665 PhoneParser handler( calendar, profileName );
568 //handler.setCategoriesList( mCategories );
569 int ccc = 0; 666 int ccc = 0;
570 while (!gshutdown && ccc++ < 10 ) { 667 while (!gshutdown && ccc++ < 10 ) {
571 668
572 qDebug("count %d ", ccc); 669 qDebug("readEvent %d ", ccc);
573 error=Phone->GetNextCalendar(&s,&note,refresh); 670 error=Phone->GetNextCalendar(&s,&note,refresh);
574 if (error == ERR_EMPTY) break; 671 if (error == ERR_EMPTY) break;
575 handler.startElement( existingCal, &note, "Event" ); 672 handler.readEvent( existingCal, &note );
576 } 673 }
674
675 bool start = true;
676 GSM_ToDoEntry ToDo;
677 int ccc = 0;
678 while (!gshutdown) {
679 error = Phone->GetNextToDo(&s, &ToDo, start);
680 if (error == ERR_EMPTY) break;
681 start = false;
682 qDebug("readTodo %d ", ++ccc);
683 handler.readTodo( existingCal, &ToDo, &s);
684
685 }
686
577 error=GSM_TerminateConnection(&s); 687 error=GSM_TerminateConnection(&s);
578#if 0
579
580 bool debug = DEBUGMODE;
581 //debug = true;
582 QString text;
583 QString codec = "utf8";
584 QLabel status ( i18n("Reading events ..."), 0 );
585
586 int w = status.sizeHint().width()+20 ;
587 if ( w < 200 ) w = 200;
588 int h = status.sizeHint().height()+20 ;
589 int dw = QApplication::desktop()->width();
590 int dh = QApplication::desktop()->height();
591 status.setCaption(i18n("Reading DTM Data") );
592 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
593 status.show();
594 status.raise();
595 qApp->processEvents();
596 QString fileName;
597 if ( ! debug ) {
598 fileName = "/tmp/kopitempout";
599 QString command ="db2file datebook -r -c "+ codec + " > " + fileName;
600 system ( command.latin1() );
601 } else {
602 fileName = "/tmp/events.txt";
603
604 }
605 QFile file( fileName );
606 if (!file.open( IO_ReadOnly ) ) {
607 return false;
608
609 }
610 QTextStream ts( &file );
611 ts.setCodec( QTextCodec::codecForName("utf8") );
612 text = ts.read();
613 file.close();
614 status.setText( i18n("Processing events ...") );
615 status.raise();
616 qApp->processEvents();
617 fromString2Cal( calendar, existngCal, text, "Event" );
618 status.setText( i18n("Reading todos ...") );
619 qApp->processEvents();
620 if ( ! debug ) {
621 fileName = "/tmp/kopitempout";
622 QString command = "db2file todo -r -c " + codec+ " > " + fileName;
623 system ( command.latin1() );
624 } else {
625 fileName = "/tmp/todo.txt";
626 }
627 file.setName( fileName );
628 if (!file.open( IO_ReadOnly ) ) {
629 return false;
630
631 }
632 ts.setDevice( &file );
633 text = ts.read();
634 file.close();
635 688
636 status.setText( i18n("Processing todos ...") );
637 status.raise();
638 qApp->processEvents();
639 fromString2Cal( calendar, existngCal, text, "Todo" );
640#endif
641 return true; 689 return true;
642} 690}
643int PhoneFormat::getNumFromRecord( QString answer, Incidence* inc ) 691
644{
645 int retval = -1;
646 QStringList templist;
647 QString tempString;
648 int start = 0;
649 int len = answer.length();
650 int end = answer.find ("\n",start)+1;
651 bool ok = true;
652 start = end;
653 int ccc = 0;
654 while ( start > 0 ) {
655 templist.clear();
656 ok = true;
657 int loopCount = 0;
658 while ( ok ) {
659 ++loopCount;
660 if ( loopCount > 25 ) {
661 qDebug("KO: Error in while loop");
662 ok = false;
663 start = 0;
664 break;
665 }
666 if ( ok )
667 tempString = getPart( answer, ok, start );
668 if ( start >= len || start == 0 ) {
669 start = 0;
670 ok = false;
671 }
672 if ( tempString.right(1) =="\n" )
673 tempString = tempString.left( tempString.length()-1);
674
675 templist.append( tempString );
676 }
677 ++ccc;
678 if ( ccc == 2 && loopCount < 25 ) {
679 start = 0;
680 bool ok;
681 int newnum = templist[0].toInt( &ok );
682 if ( ok && newnum > 0) {
683 retval = newnum;
684 //inc->setZaurusId( newnum );
685 //inc->setZaurusUid( getCsum( templist ) );
686 //inc->setZaurusStat( -4 );
687 }
688 }
689 }
690 //qDebug("getNumFromRecord returning : %d ", retval);
691 return retval;
692}
693bool PhoneFormat::save( Calendar *calendar) 692bool PhoneFormat::save( Calendar *calendar)
694{ 693{
695 694#if 0
696 QLabel status ( i18n("Processing/adding events ..."), 0 ); 695 QLabel status ( i18n("Processing/adding events ..."), 0 );
697 int w = status.sizeHint().width()+20 ; 696 int w = status.sizeHint().width()+20 ;
698 if ( w < 200 ) w = 200; 697 if ( w < 200 ) w = 200;
699 int h = status.sizeHint().height()+20 ; 698 int h = status.sizeHint().height()+20 ;
700 int dw = QApplication::desktop()->width(); 699 int dw = QApplication::desktop()->width();
701 int dh = QApplication::desktop()->height(); 700 int dh = QApplication::desktop()->height();
702 status.setCaption(i18n("Writing DTM Data") ); 701 status.setCaption(i18n("Writing DTM Data") );
703 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); 702 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
704 status.show(); 703 status.show();
705 status.raise(); 704 status.raise();
706 qApp->processEvents(); 705 qApp->processEvents();
707 bool debug = DEBUGMODE; 706 bool debug = DEBUGMODE;
708 QString codec = "utf8"; 707 QString codec = "utf8";
709 QString answer; 708 QString answer;
710 QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n"; 709 QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n";
711 QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n"; 710 QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n";
712 QString command; 711 QString command;
713 QPtrList<Event> er = calendar->rawEvents(); 712 QPtrList<Event> er = calendar->rawEvents();
714 Event* ev = er.first(); 713 Event* ev = er.first();
715 QString fileName = "/tmp/kopitempout"; 714 QString fileName = "/tmp/kopitempout";
716 int i = 0; 715 int i = 0;
717 QString changeString = ePrefix; 716 QString changeString = ePrefix;
718 QString deleteString = ePrefix; 717 QString deleteString = ePrefix;
719 bool deleteEnt = false; 718 bool deleteEnt = false;
720 bool changeEnt = false; 719 bool changeEnt = false;
721 QString message = i18n("Processing event # "); 720 QString message = i18n("Processing event # ");
722 int procCount = 0; 721 int procCount = 0;
723 while ( ev ) { 722 while ( ev ) {
724 //qDebug("i %d ", ++i); 723 //qDebug("i %d ", ++i);
725 if ( true /*ev->zaurusStat() != -2*/ ) { 724 if ( true /*ev->zaurusStat() != -2*/ ) {
726 status.setText ( message + QString::number ( ++procCount ) ); 725 status.setText ( message + QString::number ( ++procCount ) );
727 qApp->processEvents(); 726 qApp->processEvents();
728 QString eString = getEventString( ev ); 727 QString eString = getEventString( ev );
729 if (/* ev->zaurusStat() == -3 */ true) { // delete 728 if (/* ev->zaurusStat() == -3 */ true) { // delete
730 // deleting empty strings does not work. 729 // deleting empty strings does not work.
731 // we write first and x and then delete the record with the x 730 // we write first and x and then delete the record with the x
732 eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); 731 eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
733 changeString += eString + "\n"; 732 changeString += eString + "\n";
734 deleteString += eString + "\n"; 733 deleteString += eString + "\n";
735 deleteEnt = true; 734 deleteEnt = true;
736 changeEnt = true; 735 changeEnt = true;
737 } 736 }
738 else if ( /*ev->zaurusId() == -1*/true ) { // add new 737 else if ( /*ev->zaurusId() == -1*/true ) { // add new
739 command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; 738 command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
740 system ( command.utf8() ); 739 system ( command.utf8() );
741 QFile file( fileName ); 740 QFile file( fileName );
742 if (!file.open( IO_ReadOnly ) ) { 741 if (!file.open( IO_ReadOnly ) ) {
743 return false; 742 return false;
744 743
745 } 744 }
746 QTextStream ts( &file ); 745 QTextStream ts( &file );
747 ts.setCodec( QTextCodec::codecForName("utf8") ); 746 ts.setCodec( QTextCodec::codecForName("utf8") );
748 answer = ts.read(); 747 answer = ts.read();
749 file.close(); 748 file.close();
750 //qDebug("answer \n%s ", answer.latin1()); 749 //qDebug("answer \n%s ", answer.latin1());
751 getNumFromRecord( answer, ev ) ; 750 getNumFromRecord( answer, ev ) ;
752 751
753 } 752 }
754 else { // change existing 753 else { // change existing
755 //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() ); 754 //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() );
756 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; 755 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
757 changeString += eString + "\n"; 756 changeString += eString + "\n";
758 changeEnt = true; 757 changeEnt = true;
759 758
760 } 759 }
761 } 760 }
762 ev = er.next(); 761 ev = er.next();
763 } 762 }
764 status.setText ( i18n("Changing events ...") ); 763 status.setText ( i18n("Changing events ...") );
765 qApp->processEvents(); 764 qApp->processEvents();
766 //qDebug("changing... "); 765 //qDebug("changing... ");
767 if ( changeEnt ) { 766 if ( changeEnt ) {
768 QFile file( fileName ); 767 QFile file( fileName );
769 if (!file.open( IO_WriteOnly ) ) { 768 if (!file.open( IO_WriteOnly ) ) {
770 return false; 769 return false;
771 770
772 } 771 }
773 QTextStream ts( &file ); 772 QTextStream ts( &file );
774 ts.setCodec( QTextCodec::codecForName("utf8") ); 773 ts.setCodec( QTextCodec::codecForName("utf8") );
775 ts << changeString ; 774 ts << changeString ;
776 file.close(); 775 file.close();
777 command = "db2file datebook -w -g -c " + codec+ " < "+ fileName; 776 command = "db2file datebook -w -g -c " + codec+ " < "+ fileName;
778 system ( command.latin1() ); 777 system ( command.latin1() );
779 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); 778 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
780 779
781 } 780 }
782 status.setText ( i18n("Deleting events ...") ); 781 status.setText ( i18n("Deleting events ...") );
783 qApp->processEvents(); 782 qApp->processEvents();
784 //qDebug("deleting... "); 783 //qDebug("deleting... ");
785 if ( deleteEnt ) { 784 if ( deleteEnt ) {
786 QFile file( fileName ); 785 QFile file( fileName );
787 if (!file.open( IO_WriteOnly ) ) { 786 if (!file.open( IO_WriteOnly ) ) {
788 return false; 787 return false;
789 788
790 } 789 }
791 QTextStream ts( &file ); 790 QTextStream ts( &file );
792 ts.setCodec( QTextCodec::codecForName("utf8") ); 791 ts.setCodec( QTextCodec::codecForName("utf8") );
793 ts << deleteString; 792 ts << deleteString;
794 file.close(); 793 file.close();
795 command = "db2file datebook -d -c " + codec+ " < "+ fileName; 794 command = "db2file datebook -d -c " + codec+ " < "+ fileName;
796 system ( command.latin1() ); 795 system ( command.latin1() );
797 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); 796 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
798 } 797 }
799 798
800 799
801 changeString = tPrefix; 800 changeString = tPrefix;
802 deleteString = tPrefix; 801 deleteString = tPrefix;
803 status.setText ( i18n("Processing todos ...") ); 802 status.setText ( i18n("Processing todos ...") );
804 qApp->processEvents(); 803 qApp->processEvents();
805 QPtrList<Todo> tl = calendar->rawTodos(); 804 QPtrList<Todo> tl = calendar->rawTodos();
806 Todo* to = tl.first(); 805 Todo* to = tl.first();
807 i = 0; 806 i = 0;
808 message = i18n("Processing todo # "); 807 message = i18n("Processing todo # ");
809 procCount = 0; 808 procCount = 0;
810 while ( to ) { 809 while ( to ) {
811 if ( true /*to->zaurusStat() != -2 */) { 810 if ( true /*to->zaurusStat() != -2 */) {
812 status.setText ( message + QString::number ( ++procCount ) ); 811 status.setText ( message + QString::number ( ++procCount ) );
813 qApp->processEvents(); 812 qApp->processEvents();
814 QString eString = getTodoString( to ); 813 QString eString = getTodoString( to );
815 if ( /*to->zaurusStat() == -3*/true ) { // delete 814 if ( /*to->zaurusStat() == -3*/true ) { // delete
816 // deleting empty strings does not work. 815 // deleting empty strings does not work.
817 // we write first and x and then delete the record with the x 816 // we write first and x and then delete the record with the x
818 eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); 817 eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
819 changeString += eString + "\n"; 818 changeString += eString + "\n";
820 deleteString += eString + "\n"; 819 deleteString += eString + "\n";
821 deleteEnt = true; 820 deleteEnt = true;
822 changeEnt = true; 821 changeEnt = true;
823 } 822 }
824 else if ( true /*to->zaurusId() == -1*/ ) { // add new 823 else if ( true /*to->zaurusId() == -1*/ ) { // add new
825 command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName; 824 command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName;
826 system ( command.utf8() ); 825 system ( command.utf8() );
827 QFile file( fileName ); 826 QFile file( fileName );
828 if (!file.open( IO_ReadOnly ) ) { 827 if (!file.open( IO_ReadOnly ) ) {
829 return false; 828 return false;
830 829
831 } 830 }
832 QTextStream ts( &file ); 831 QTextStream ts( &file );
833 ts.setCodec( QTextCodec::codecForName("utf8") ); 832 ts.setCodec( QTextCodec::codecForName("utf8") );
834 answer = ts.read(); 833 answer = ts.read();
835 file.close(); 834 file.close();
836 //qDebug("answer \n%s ", answer.latin1()); 835 //qDebug("answer \n%s ", answer.latin1());
837 getNumFromRecord( answer, to ) ; 836 getNumFromRecord( answer, to ) ;
838 837
839 } 838 }
840 else { // change existing 839 else { // change existing
841 //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() ); 840 //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() );
842 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; 841 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
843 changeString += eString + "\n"; 842 changeString += eString + "\n";
844 changeEnt = true; 843 changeEnt = true;
845 844
846 } 845 }
847 } 846 }
848 847
849 to = tl.next(); 848 to = tl.next();
850 } 849 }
851 status.setText ( i18n("Changing todos ...") ); 850 status.setText ( i18n("Changing todos ...") );
852 qApp->processEvents(); 851 qApp->processEvents();
853 //qDebug("changing... "); 852 //qDebug("changing... ");
854 if ( changeEnt ) { 853 if ( changeEnt ) {
855 QFile file( fileName ); 854 QFile file( fileName );
856 if (!file.open( IO_WriteOnly ) ) { 855 if (!file.open( IO_WriteOnly ) ) {
857 return false; 856 return false;
858 857
859 } 858 }
860 QTextStream ts( &file ); 859 QTextStream ts( &file );
861 ts.setCodec( QTextCodec::codecForName("utf8") ); 860 ts.setCodec( QTextCodec::codecForName("utf8") );
862 ts << changeString ; 861 ts << changeString ;
863 file.close(); 862 file.close();
864 command = "db2file todo -w -g -c " + codec+ " < "+ fileName; 863 command = "db2file todo -w -g -c " + codec+ " < "+ fileName;
865 system ( command.latin1() ); 864 system ( command.latin1() );
866 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); 865 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
867 866
868 } 867 }
869 status.setText ( i18n("Deleting todos ...") ); 868 status.setText ( i18n("Deleting todos ...") );
870 qApp->processEvents(); 869 qApp->processEvents();
871 //qDebug("deleting... "); 870 //qDebug("deleting... ");
872 if ( deleteEnt ) { 871 if ( deleteEnt ) {
873 QFile file( fileName ); 872 QFile file( fileName );
874 if (!file.open( IO_WriteOnly ) ) { 873 if (!file.open( IO_WriteOnly ) ) {
875 return false; 874 return false;
876 875
877 } 876 }
878 QTextStream ts( &file ); 877 QTextStream ts( &file );
879 ts.setCodec( QTextCodec::codecForName("utf8") ); 878 ts.setCodec( QTextCodec::codecForName("utf8") );
880 ts << deleteString; 879 ts << deleteString;
881 file.close(); 880 file.close();
882 command = "db2file todo -d -c " + codec+ " < "+ fileName; 881 command = "db2file todo -d -c " + codec+ " < "+ fileName;
883 system ( command.latin1() ); 882 system ( command.latin1() );
884 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); 883 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
885 } 884 }
886 885#endif
887 return true; 886 return true;
888} 887}
889QString PhoneFormat::dtToString( const QDateTime& dti, bool useTZ ) 888QString PhoneFormat::dtToGSM( const QDateTime& dti, bool useTZ )
890{ 889{
891 QString datestr; 890 QString datestr;
892 QString timestr; 891 QString timestr;
893 int offset = KGlobal::locale()->localTimeOffset( dti ); 892 int offset = KGlobal::locale()->localTimeOffset( dti );
894 QDateTime dt; 893 QDateTime dt;
895 if (useTZ) 894 if (useTZ)
896 dt = dti.addSecs ( -(offset*60)); 895 dt = dti.addSecs ( -(offset*60));
897 else 896 else
898 dt = dti; 897 dt = dti;
899 if(dt.date().isValid()){ 898 if(dt.date().isValid()){
900 const QDate& date = dt.date(); 899 const QDate& date = dt.date();
901 datestr.sprintf("%04d%02d%02d", 900 datestr.sprintf("%04d%02d%02d",
902 date.year(), date.month(), date.day()); 901 date.year(), date.month(), date.day());
903 } 902 }
904 if(dt.time().isValid()){ 903 if(dt.time().isValid()){
905 const QTime& time = dt.time(); 904 const QTime& time = dt.time();
906 timestr.sprintf("T%02d%02d%02d", 905 timestr.sprintf("T%02d%02d%02d",
907 time.hour(), time.minute(), time.second()); 906 time.hour(), time.minute(), time.second());
908 } 907 }
909 return datestr + timestr; 908 return datestr + timestr;
910} 909}
911QString PhoneFormat::getEventString( Event* event ) 910QString PhoneFormat::getEventString( Event* event )
912{ 911{
913#if 0 912#if 0
914 QStringList list; 913 QStringList list;
915 list.append( QString::number(event->zaurusId() ) ); 914 list.append( QString::number(event->zaurusId() ) );
916 list.append( event->categories().join(",") ); 915 list.append( event->categories().join(",") );
917 if ( !event->summary().isEmpty() ) 916 if ( !event->summary().isEmpty() )
918 list.append( event->summary() ); 917 list.append( event->summary() );
919 else 918 else
920 list.append("" ); 919 list.append("" );
921 if ( !event->location().isEmpty() ) 920 if ( !event->location().isEmpty() )
922 list.append( event->location() ); 921 list.append( event->location() );
923 else 922 else
924 list.append("" ); 923 list.append("" );
925 if ( !event->description().isEmpty() ) 924 if ( !event->description().isEmpty() )
926 list.append( event->description() ); 925 list.append( event->description() );
927 else 926 else
928 list.append( "" ); 927 list.append( "" );
929 if ( event->doesFloat () ) { 928 if ( event->doesFloat () ) {
930 list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); 929 list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false ));
931 list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 930 list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6
932 list.append( "1" ); 931 list.append( "1" );
933 932
934 } 933 }
935 else { 934 else {
936 list.append( dtToString( event->dtStart()) ); 935 list.append( dtToString( event->dtStart()) );
937 list.append( dtToString( event->dtEnd()) ); //6 936 list.append( dtToString( event->dtEnd()) ); //6
938 list.append( "0" ); 937 list.append( "0" );
939 } 938 }
940 bool noAlarm = true; 939 bool noAlarm = true;
941 if ( event->alarms().count() > 0 ) { 940 if ( event->alarms().count() > 0 ) {
942 Alarm * al = event->alarms().first(); 941 Alarm * al = event->alarms().first();
943 if ( al->enabled() ) { 942 if ( al->enabled() ) {
944 noAlarm = false; 943 noAlarm = false;
945 list.append( "0" ); // yes, 0 == alarm 944 list.append( "0" ); // yes, 0 == alarm
946 list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); 945 list.append( QString::number( al->startOffset().asSeconds()/(-60) ) );
947 if ( al->type() == Alarm::Audio ) 946 if ( al->type() == Alarm::Audio )
948 list.append( "1" ); // type audio 947 list.append( "1" ); // type audio
949 else 948 else
950 list.append( "0" ); // type silent 949 list.append( "0" ); // type silent
951 } 950 }
952 } 951 }
953 if ( noAlarm ) { 952 if ( noAlarm ) {
954 list.append( "1" ); // yes, 1 == no alarm 953 list.append( "1" ); // yes, 1 == no alarm
955 list.append( "0" ); // no alarm offset 954 list.append( "0" ); // no alarm offset
@@ -1013,505 +1012,127 @@ QString PhoneFormat::getEventString( Event* event )
1013 list.append( "0" ); 1012 list.append( "0" );
1014 list.append( "0" ); 1013 list.append( "0" );
1015 writeEndDate = true; 1014 writeEndDate = true;
1016 break; 1015 break;
1017 case Recurrence::rYearlyMonth://4 1016 case Recurrence::rYearlyMonth://4
1018 list.append( "4" ); 1017 list.append( "4" );
1019 list.append( QString::number( rec->frequency()) );//12 1018 list.append( QString::number( rec->frequency()) );//12
1020 list.append( "0" ); 1019 list.append( "0" );
1021 list.append( "0" ); 1020 list.append( "0" );
1022 writeEndDate = true; 1021 writeEndDate = true;
1023 break; 1022 break;
1024 1023
1025 default: 1024 default:
1026 list.append( "255" ); 1025 list.append( "255" );
1027 list.append( QString() ); 1026 list.append( QString() );
1028 list.append( "0" ); 1027 list.append( "0" );
1029 list.append( QString() ); 1028 list.append( QString() );
1030 list.append( "0" ); 1029 list.append( "0" );
1031 list.append( "20991231T000000" ); 1030 list.append( "20991231T000000" );
1032 break; 1031 break;
1033 } 1032 }
1034 if ( writeEndDate ) { 1033 if ( writeEndDate ) {
1035 1034
1036 if ( rec->endDate().isValid() ) { // 15 + 16 1035 if ( rec->endDate().isValid() ) { // 15 + 16
1037 list.append( "1" ); 1036 list.append( "1" );
1038 list.append( dtToString( rec->endDate()) ); 1037 list.append( dtToString( rec->endDate()) );
1039 } else { 1038 } else {
1040 list.append( "0" ); 1039 list.append( "0" );
1041 list.append( "20991231T000000" ); 1040 list.append( "20991231T000000" );
1042 } 1041 }
1043 1042
1044 } 1043 }
1045 if ( event->doesFloat () ) { 1044 if ( event->doesFloat () ) {
1046 list.append( dtToString( event->dtStart(), false ).left( 8 )); 1045 list.append( dtToString( event->dtStart(), false ).left( 8 ));
1047 list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6 1046 list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6
1048 1047
1049 } 1048 }
1050 else { 1049 else {
1051 list.append( QString() ); 1050 list.append( QString() );
1052 list.append( QString() ); 1051 list.append( QString() );
1053 1052
1054 } 1053 }
1055 if (event->dtStart().date() == event->dtEnd().date() ) 1054 if (event->dtStart().date() == event->dtEnd().date() )
1056 list.append( "0" ); 1055 list.append( "0" );
1057 else 1056 else
1058 list.append( "1" ); 1057 list.append( "1" );
1059 1058
1060 1059
1061 for(QStringList::Iterator it=list.begin(); 1060 for(QStringList::Iterator it=list.begin();
1062 it!=list.end(); ++it){ 1061 it!=list.end(); ++it){
1063 QString& s = (*it); 1062 QString& s = (*it);
1064 s.replace(QRegExp("\""), "\"\""); 1063 s.replace(QRegExp("\""), "\"\"");
1065 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ 1064 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
1066 s.prepend('\"'); 1065 s.prepend('\"');
1067 s.append('\"'); 1066 s.append('\"');
1068 } else if(s.isEmpty() && !s.isNull()){ 1067 } else if(s.isEmpty() && !s.isNull()){
1069 s = "\"\""; 1068 s = "\"\"";
1070 } 1069 }
1071 } 1070 }
1072 return list.join(","); 1071 return list.join(",");
1073#endif 1072#endif
1074 return QString(); 1073 return QString();
1075 1074
1076} 1075}
1077QString PhoneFormat::getTodoString( Todo* todo ) 1076QString PhoneFormat::getTodoString( Todo* todo )
1078{ 1077{
1079#if 0 1078#if 0
1080 QStringList list; 1079 QStringList list;
1081 list.append( QString::number( todo->zaurusId() ) ); 1080 list.append( QString::number( todo->zaurusId() ) );
1082 list.append( todo->categories().join(",") ); 1081 list.append( todo->categories().join(",") );
1083 1082
1084 if ( todo->hasStartDate() ) { 1083 if ( todo->hasStartDate() ) {
1085 list.append( dtToString( todo->dtStart()) ); 1084 list.append( dtToString( todo->dtStart()) );
1086 } else 1085 } else
1087 list.append( QString() ); 1086 list.append( QString() );
1088 1087
1089 if ( todo->hasDueDate() ) { 1088 if ( todo->hasDueDate() ) {
1090 QTime tim; 1089 QTime tim;
1091 if ( todo->doesFloat()) { 1090 if ( todo->doesFloat()) {
1092 list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; 1091 list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ;
1093 } else { 1092 } else {
1094 list.append( dtToString(todo->dtDue() ) ); 1093 list.append( dtToString(todo->dtDue() ) );
1095 } 1094 }
1096 } else 1095 } else
1097 list.append( QString() ); 1096 list.append( QString() );
1098 1097
1099 if ( todo->isCompleted() ) { 1098 if ( todo->isCompleted() ) {
1100 list.append( dtToString( todo->completed()) ); 1099 list.append( dtToString( todo->completed()) );
1101 list.append( "0" ); // yes 0 == completed 1100 list.append( "0" ); // yes 0 == completed
1102 } else { 1101 } else {
1103 list.append( dtToString( todo->completed()) ); 1102 list.append( dtToString( todo->completed()) );
1104 list.append( "1" ); 1103 list.append( "1" );
1105 } 1104 }
1106 list.append( QString::number( todo->priority() )); 1105 list.append( QString::number( todo->priority() ));
1107 if( ! todo->summary().isEmpty() ) 1106 if( ! todo->summary().isEmpty() )
1108 list.append( todo->summary() ); 1107 list.append( todo->summary() );
1109 else 1108 else
1110 list.append( "" ); 1109 list.append( "" );
1111 if (! todo->description().isEmpty() ) 1110 if (! todo->description().isEmpty() )
1112 list.append( todo->description() ); 1111 list.append( todo->description() );
1113 else 1112 else
1114 list.append( "" ); 1113 list.append( "" );
1115 for(QStringList::Iterator it=list.begin(); 1114 for(QStringList::Iterator it=list.begin();
1116 it!=list.end(); ++it){ 1115 it!=list.end(); ++it){
1117 QString& s = (*it); 1116 QString& s = (*it);
1118 s.replace(QRegExp("\""), "\"\""); 1117 s.replace(QRegExp("\""), "\"\"");
1119 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ 1118 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
1120 s.prepend('\"'); 1119 s.prepend('\"');
1121 s.append('\"'); 1120 s.append('\"');
1122 } else if(s.isEmpty() && !s.isNull()){ 1121 } else if(s.isEmpty() && !s.isNull()){
1123 s = "\"\""; 1122 s = "\"\"";
1124 } 1123 }
1125 } 1124 }
1126 return list.join(","); 1125 return list.join(",");
1127#endif 1126#endif
1128 return QString(); 1127 return QString();
1129} 1128}
1130QString PhoneFormat::getPart( const QString & text, bool &ok, int &start )
1131{
1132 //qDebug("start %d ", start);
1133
1134 QString retval ="";
1135 if ( text.at(start) == '"' ) {
1136 if ( text.mid( start,2) == "\"\"" && !( text.mid( start+2,1) == "\"")) {
1137 start = start +2;
1138 if ( text.mid( start,1) == "," ) {
1139 start += 1;
1140 }
1141 retval = "";
1142 if ( text.mid( start,1) == "\n" ) {
1143 start += 1;
1144 ok = false;
1145 }
1146 return retval;
1147 }
1148 int hk = start+1;
1149 hk = text.find ('"',hk);
1150 while ( text.at(hk+1) == '"' )
1151 hk = text.find ('"',hk+2);
1152 retval = text.mid( start+1, hk-start-1);
1153 start = hk+1;
1154 retval.replace( QRegExp("\"\""), "\"");
1155 if ( text.mid( start,1) == "," ) {
1156 start += 1;
1157 }
1158 if ( text.mid( start,1) == "\n" ) {
1159 start += 1;
1160 ok = false;
1161 }
1162 //qDebug("retval***%s*** ",retval.latin1() );
1163 return retval;
1164 1129
1165 } else { 1130
1166 int nl = text.find ("\n",start); 1131QString PhoneFormat::toString( Calendar * )
1167 int kom = text.find (',',start);
1168 if ( kom < nl ) {
1169 // qDebug("kom < nl %d ", kom);
1170 retval = text.mid(start, kom-start);
1171 start = kom+1;
1172 return retval;
1173 } else {
1174 if ( nl == kom ) {
1175 // qDebug(" nl == kom ");
1176 start = 0;
1177 ok = false;
1178 return "0";
1179 }
1180 // qDebug(" nl < kom ", nl);
1181 retval = text.mid( start, nl-start);
1182 ok = false;
1183 start = nl+1;
1184 return retval;
1185 }
1186 }
1187}
1188bool PhoneFormat::fromString( Calendar *calendar, const QString & text)
1189{ 1132{
1190 return false; 1133 return QString::null;
1191} 1134}
1192 bool PhoneFormat::fromString2Cal( Calendar *calendar,Calendar *existingCalendar, GSM_StateMachine*s, const QString & type) 1135bool PhoneFormat::fromString( Calendar *calendar, const QString & text)
1193{ 1136{
1194#if 0
1195 GSM_Phone_Functions*Phone;
1196
1197 GSM_CalendarEntrynote;
1198 GSM_CalendarEntry*Note;
1199 bool refresh= true;
1200
1201 Phone=s->Phone.Functions;
1202 bool gshutdown = false;
1203 PhoneParser handler( calendar );
1204 //handler.setCategoriesList( mCategories );
1205 QStringList templist;
1206 QString tempString;
1207 int start = 0;
1208 int error;
1209 int ccc = 0;
1210 while (!gshutdown && ccc++ < 10 ) {
1211 QString CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY;
1212 templist.clear();
1213 qDebug("count %d ", ccc);
1214 error=Phone->GetNextCalendar(s,&note,refresh);
1215 if (error == ERR_EMPTY) break;
1216
1217 Note = &note;
1218//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY
1219// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1220
1221//ARSD silentalarm = 0
1222// 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly
1223// 12 RFRQ
1224// 13 RPOS pos = 4. monday in month
1225// 14 RDYS days: 1 mon/ 2 tue .. 64 sun
1226// 15 REND 0 = no end/ 1 = end
1227// 16 REDT rec end dt
1228//ALSD
1229//ALED
1230//MDAY
1231
1232 CARDID = QString::number( Note->Location ); // 0
1233
1234
1235 int i_age = 0,i;
1236 GSM_DateTime Alarm,DateTime;
1237 GSM_DateTime* dtp;
1238 GSM_MemoryEntry entry;
1239 unsigned char *name;
1240
1241 bool repeating = false;
1242 int repeat_dayofweek = -1;
1243 int repeat_day = -1;
1244 int repeat_weekofmonth = -1;
1245 int repeat_month = -1;
1246 int repeat_frequency = -1;
1247 GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0};
1248 GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0};
1249
1250 Alarm.Year = 0;
1251
1252 repeating = false;
1253 repeat_dayofweek = -1;
1254 repeat_day = -1;
1255 repeat_weekofmonth = -1;
1256 repeat_month = -1;
1257 repeat_frequency = -1;
1258 repeat_startdate.Day= 0;
1259 repeat_stopdate.Day = 0;
1260
1261
1262 switch (Note->Type) {
1263 case GSM_CAL_REMINDER : CATEGORY = QString("Reminder"); break;
1264 case GSM_CAL_CALL : CATEGORY = QString("Call"); break;
1265 case GSM_CAL_MEETING : CATEGORY = QString("Meeting"); break;
1266 case GSM_CAL_BIRTHDAY : CATEGORY = QString("Birthday"); break;
1267 case GSM_CAL_MEMO : CATEGORY = QString("Memo"); break;
1268 case GSM_CAL_TRAVEL : CATEGORY = QString("Travel"); break;
1269 case GSM_CAL_VACATION : CATEGORY = QString("Vacation"); break;
1270 case GSM_CAL_ALARM : CATEGORY = QString("Alarm"); break;
1271 case GSM_CAL_DAILY_ALARM : CATEGORY = QString("Daily alarm"); break;
1272 case GSM_CAL_T_ATHL : CATEGORY = QString("Training/Athletism"); break;
1273 case GSM_CAL_T_BALL : CATEGORY = QString("Training/Ball Games"); break;
1274 case GSM_CAL_T_CYCL : CATEGORY = QString("Training/Cycling"); break;
1275 case GSM_CAL_T_BUDO : CATEGORY = QString("Training/Budo"); break;
1276 case GSM_CAL_T_DANC : CATEGORY = QString("Training/Dance"); break;
1277 case GSM_CAL_T_EXTR : CATEGORY = QString("Training/Extreme Sports"); break;
1278 case GSM_CAL_T_FOOT : CATEGORY = QString("Training/Football"); break;
1279 case GSM_CAL_T_GOLF : CATEGORY = QString("Training/Golf"); break;
1280 case GSM_CAL_T_GYM : CATEGORY = QString("Training/Gym"); break;
1281 case GSM_CAL_T_HORS : CATEGORY = QString("Training/Horse Races"); break;
1282 case GSM_CAL_T_HOCK : CATEGORY = QString("Training/Hockey"); break;
1283 case GSM_CAL_T_RACE : CATEGORY = QString("Training/Races"); break;
1284 case GSM_CAL_T_RUGB : CATEGORY = QString("Training/Rugby"); break;
1285 case GSM_CAL_T_SAIL : CATEGORY = QString("Training/Sailing"); break;
1286 case GSM_CAL_T_STRE : CATEGORY = QString("Training/Street Games"); break;
1287 case GSM_CAL_T_SWIM : CATEGORY = QString("Training/Swimming"); break;
1288 case GSM_CAL_T_TENN : CATEGORY = QString("Training/Tennis"); break;
1289 case GSM_CAL_T_TRAV : CATEGORY = QString("Training/Travels"); break;
1290 case GSM_CAL_T_WINT : CATEGORY = QString("Training/Winter Games"); break;
1291 default : CATEGORY = QString("");
1292 }
1293//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY
1294// 0x 1x 2x 3x 4x 5x 6x 7x 8x 9x 10? 11 12 13 14 15 16 17x 18x 19?
1295
1296 MEM1 = "";
1297
1298#if 0
1299
1300 if ( attList[7] == "1" ) {
1301 event->setDtStart( QDateTime(fromString( attList[17]+"000000", false ).date(),QTime(0,0,0 ) ));
1302 event->setDtEnd( QDateTime(fromString( attList[18]+"000000", false ).date(),QTime(0,0,0 )));
1303 event->setFloats( true );
1304 } else {
1305 event->setFloats( false );
1306 event->setDtStart( fromString( attList[5] ) );
1307 event->setDtEnd( fromString( attList[6] ));
1308 }
1309
1310
1311
1312typedef struct {
1313 /**
1314 * The difference between local time and GMT in hours
1315 */
1316 int Timezone;
1317
1318 unsigned int Second;
1319 unsigned int Minute;
1320 unsigned int Hour;
1321
1322 unsigned int Day;
1323 /**
1324 * January = 1, February = 2, etc.
1325 */
1326 unsigned int Month;
1327 /**
1328 * Complete year number. Not 03, but 2003
1329 */
1330 unsigned int Year;
1331} GSM_DateTime;
1332
1333 if(dt.date().isValid()){
1334 const QDate& date = dt.date();
1335 datestr.sprintf("%04d%02d%02d",
1336 date.year(), date.month(), date.day());
1337 }
1338 if(dt.time().isValid()){
1339 const QTime& time = dt.time();
1340 timestr.sprintf("T%02d%02d%02d",
1341 time.hour(), time.minute(), time.second());
1342 }
1343 return datestr + timestr;
1344
1345
1346
1347
1348#endif
1349
1350
1351 ADAY = "0";
1352 ARON = "1"; // 1 == disabled
1353 ARMN = "0"; //alarm offset in minutes
1354
1355 for (i=0;i<Note->EntriesNum;i++) {
1356
1357 qDebug(" for ");
1358 switch (Note->Entries[i].EntryType) {
1359 case CAL_START_DATETIME:
1360 dtp = &Note->Entries[i].Date ;
1361
1362 qDebug("hour: %d ", dtp->Hour);
1363 if ( dtp->Hour == -1 ) {
1364 ADAY = "1";
1365 ALSD.sprintf("%04d%02d%02d",dtp->Year, dtp->Month, dtp->Day );
1366 TIM1.sprintf("%04d%02d%02dT000000",dtp->Year, dtp->Month, dtp->Day );
1367 } else {
1368 TIM1.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second );
1369
1370 }
1371 ////printmsg("Start : %s\n",OSDateTime(Note->Entries[i].Date,false));
1372 //memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime));
1373 break;
1374 case CAL_END_DATETIME:
1375 dtp = &Note->Entries[i].Date ;
1376 qDebug("hour2: %d ", dtp->Hour);
1377 if ( dtp->Hour == -1 ) {
1378 ADAY = "1";
1379 ALED.sprintf("%04d%02d%02d",dtp->Year, dtp->Month, dtp->Day );
1380 TIM2.sprintf("%04d%02d%02dT000000",dtp->Year, dtp->Month, dtp->Day );
1381 } else {
1382 TIM2.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second );
1383
1384 }
1385 //printmsg("Stop : %s\n",OSDateTime(Note->Entries[i].Date,false));
1386 //memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime));
1387 break;
1388 case CAL_ALARM_DATETIME:
1389 ARON = "0";
1390 dtp = &Note->Entries[i].Date ;
1391 ARMN.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second );
1392 //printmsg("Tone alarm : %s\n",OSDateTime(Note->Entries[i].Date,false));
1393 memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime));
1394 break;
1395 case CAL_SILENT_ALARM_DATETIME:
1396 ARON = "0";
1397 dtp = &Note->Entries[i].Date ;
1398 ARMN.sprintf("%04d%02d%02dT%02d%02d%02d",dtp->Year, dtp->Month, dtp->Day, dtp->Hour - dtp->Timezone, dtp->Minute, dtp->Second );
1399 //printmsg("Silent alarm : %s\n",OSDateTime(Note->Entries[i].Date,false));
1400 //memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime));
1401 break;
1402 case CAL_RECURRANCE:
1403 //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" );
1404 break;
1405 case CAL_TEXT:
1406 DSRP = QString ( (const char*) Note->Entries[i].Text );
1407 break;
1408 case CAL_LOCATION:
1409 PLCE = QString ((const char*) Note->Entries[i].Text );
1410 break;
1411 case CAL_PHONE:
1412 //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text));
1413 break;
1414 case CAL_PRIVATE:
1415 //printmsg("Private : %s\n",Note->Entries[i].Number == 1 ? "Yes" : "No");
1416 break;
1417 case CAL_CONTACTID:
1418#if 0
1419 entry.Location = Note->Entries[i].Number;
1420 entry.MemoryType = MEM_ME;
1421 error=Phone->GetMemory(&s, &entry);
1422 if (error == ERR_NONE) {
1423 name = GSM_PhonebookGetEntryName(&entry);
1424 if (name != NULL) {
1425 //printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number);
1426 } else {
1427 //printmsg("Contact ID : %d\n",Note->Entries[i].Number);
1428 }
1429 } else {
1430 //printmsg("Contact ID : %d\n",Note->Entries[i].Number);
1431 }
1432#endif
1433 break;
1434 case CAL_REPEAT_DAYOFWEEK:
1435 repeat_dayofweek = Note->Entries[i].Number;
1436 repeating = true;
1437 break;
1438 case CAL_REPEAT_DAY:
1439 repeat_day = Note->Entries[i].Number;
1440 repeating = true;
1441 break;
1442 case CAL_REPEAT_WEEKOFMONTH:
1443 repeat_weekofmonth = Note->Entries[i].Number;
1444 repeating = true;
1445 break;
1446 case CAL_REPEAT_MONTH:
1447 repeat_month = Note->Entries[i].Number;
1448 repeating = true;
1449 break;
1450 case CAL_REPEAT_FREQUENCY:
1451 repeat_frequency = Note->Entries[i].Number;
1452 repeating = true;
1453 break;
1454 case CAL_REPEAT_STARTDATE:
1455 repeat_startdate = Note->Entries[i].Date;
1456 repeating = true;
1457 break;
1458 case CAL_REPEAT_STOPDATE:
1459 repeat_stopdate = Note->Entries[i].Date;
1460 repeating = true;
1461 break;
1462 }
1463 }
1464
1465
1466
1467 if ( ARON == "0" ) {
1468 QDateTime start,alarm;
1469 start = handler.fromString( TIM1 );
1470 alarm = handler.fromString( ARMN );
1471 int min = alarm.secsTo ( start )/60;
1472 ARMN = QString::number ( min );
1473 }
1474
1475 templist.clear();
1476 templist << CARDID << CATEGORY << DSRP << PLCE << MEM1 << TIM1 << TIM2 << ADAY << ARON << ARMN << ARSD << RTYP << RFRQ << RPOS << RDYS << REND << REDT << ALSD << ALED << MDAY;
1477 handler.startElement( existingCalendar, templist, type );
1478 }
1479
1480
1481#endif
1482#if 0
1483 // qDebug("test %s ", text.latin1());
1484 QStringList templist;
1485 QString tempString;
1486 int start = 0;
1487 int len = text.length();
1488 int end = text.find ("\n",start)+1;
1489 bool ok = true;
1490 start = end;
1491 PhoneParser handler( calendar );
1492 handler.setCategoriesList( mCategories );
1493 while ( start > 0 ) {
1494 templist.clear();
1495 ok = true;
1496 while ( ok ) {
1497 tempString = getPart( text, ok, start );
1498 if ( start >= len || start == 0 ) {
1499 start = 0;
1500 ok = false;
1501 }
1502 if ( tempString.right(1) =="\n" )
1503 tempString = tempString.left( tempString.length()-1);
1504 //if ( ok )
1505 templist.append( tempString );
1506 //qDebug("%d ---%s---", templist.count(),tempString.latin1() );
1507 }
1508 handler.startElement( existingCalendar, templist, type );
1509 }
1510#endif
1511 return false; 1137 return false;
1512} 1138}
1513
1514QString PhoneFormat::toString( Calendar * )
1515{
1516 return QString::null;
1517}
diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h
index 4da38c8..8d4e200 100644
--- a/libkcal/phoneformat.h
+++ b/libkcal/phoneformat.h
@@ -1,66 +1,60 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 3
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21#ifndef PHONEFORMAT_H 21#ifndef PHONEFORMAT_H
22#define PHONEFORMAT_H 22#define PHONEFORMAT_H
23 23
24#include <qstring.h> 24#include <qstring.h>
25 25
26#include "scheduler.h" 26#include "scheduler.h"
27 27
28#include "calformat.h" 28#include "calformat.h"
29extern "C" { 29extern "C" {
30#include "../gammu/emb/common/gammu.h" 30#include "../gammu/emb/common/gammu.h"
31} 31}
32 32
33namespace KCal { 33namespace KCal {
34 34
35/** 35/**
36 This class implements the calendar format used by Phone. 36 This class implements the calendar format used by Phone.
37*/ 37*/
38 38
39class PhoneFormat : public QObject { 39class PhoneFormat : public QObject {
40 public: 40 public:
41 /** Create new iCalendar format. */ 41 /** Create new iCalendar format. */
42 PhoneFormat(); 42 PhoneFormat();
43 virtual ~PhoneFormat(); 43 virtual ~PhoneFormat();
44 44
45 bool load( Calendar * ,Calendar *, QString profileName, QString device,QString connection, QString model ); 45 bool load( Calendar * ,Calendar *, QString profileName, QString device,QString connection, QString model );
46 bool save( Calendar * ); 46 bool save( Calendar * );
47 void setCategoriesList ( QStringList * cat ){ mCategories = cat; }
48 bool fromString2Cal( Calendar *, Calendar *, GSM_StateMachine*s , const QString & );
49 bool fromString( Calendar *, const QString & ); 47 bool fromString( Calendar *, const QString & );
50 QString toString( Calendar * ); 48 QString toString( Calendar * );
51 static ulong getCsum( const QStringList & ); 49 static ulong getCsum( const QStringList & );
52 50
53 private: 51 private:
54 QString getEventString( Event* ); 52 QString getEventString( Event* );
55 QString getTodoString( Todo* ); 53 QString getTodoString( Todo* );
56 QString dtToString( const QDateTime& dt, bool useTZ = true ); 54 QString dtToGSM( const QDateTime& dt, bool useTZ = true );
57
58 QStringList *mCategories;
59 int getNumFromRecord( QString answer,Incidence* inc ) ;
60 QString getPart( const QString & text, bool &ok, int &start );
61 QString mProfileName; 55 QString mProfileName;
62}; 56};
63 57
64} 58}
65 59
66#endif 60#endif