libkcal

qtopiaformat.cpp
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
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
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include <tqdatetime.h>
23 #include <tqstring.h>
24 #include <tqptrlist.h>
25 #include <tqregexp.h>
26 #include <tqclipboard.h>
27 #include <tqfile.h>
28 #include <tqtextstream.h>
29 #include <tqxml.h>
30 
31 #include <kdebug.h>
32 #include <tdelocale.h>
33 
34 #include "calendar.h"
35 #include "calendarlocal.h"
36 
37 #include "qtopiaformat.h"
38 
39 using namespace KCal;
40 
41 class TQtopiaParser : public TQXmlDefaultHandler
42 {
43  public:
44  TQtopiaParser( Calendar *calendar ) : mCalendar( calendar ) {}
45 
46  bool startElement( const TQString &, const TQString &, const TQString & qName,
47  const TQXmlAttributes &attributes )
48  {
49  if ( qName == "event" ) {
50  Event *event = new Event;
51  TQString uid = "TQtopia" + attributes.value( "uid" );
52  event->setUid( uid );
53 
54  event->setSummary( attributes.value( "description" ) );
55  event->setLocation( attributes.value( "location" ) );
56  event->setDescription( attributes.value( "note" ) );
57  event->setDtStart( toDateTime( attributes.value( "start" ) ) );
58  event->setDtEnd( toDateTime( attributes.value( "end" ) ) );
59 
60  if ( attributes.value( "type" ) == "AllDay" ) {
61  event->setFloats( true );
62  } else {
63  event->setFloats( false );
64  }
65 
66  TQString rtype = attributes.value( "rtype" );
67  if ( !rtype.isEmpty() ) {
68  TQDate startDate = event->dtStart().date();
69 
70  TQString freqStr = attributes.value( "rfreq" );
71  int freq = freqStr.toInt();
72 
73  TQString hasEndDateStr = attributes.value( "rhasenddate" );
74  bool hasEndDate = hasEndDateStr == "1";
75 
76  TQString endDateStr = attributes.value( "enddt" );
77  TQDate endDate = toDateTime( endDateStr ).date();
78 
79  TQString weekDaysStr = attributes.value( "rweekdays" );
80  int weekDaysNum = weekDaysStr.toInt();
81  TQBitArray weekDays( 7 );
82  int i;
83  for( i = 1; i <= 7; ++i ) {
84  weekDays.setBit( i - 1, ( 2 << i ) & weekDaysNum );
85  }
86 
87  TQString posStr = attributes.value( "rposition" );
88  int pos = posStr.toInt();
89 
90  Recurrence *r = event->recurrence();
91 
92  if ( rtype == "Daily" ) {
93  r->setDaily( freq );
94  if ( hasEndDate ) r->setEndDate( endDate );
95  } else if ( rtype == "Weekly" ) {
96  r->setWeekly( freq, weekDays );
97  if ( hasEndDate ) r->setEndDate( endDate );
98  } else if ( rtype == "MonthlyDate" ) {
99  r->setMonthly( freq );
100  if ( hasEndDate )
101  r->setEndDate( endDate );
102  r->addMonthlyDate( startDate.day() );
103  } else if ( rtype == "MonthlyDay" ) {
104  r->setMonthly( freq );
105  if ( hasEndDate )
106  r->setEndDate( endDate );
107  TQBitArray days( 7 );
108  days.fill( false );
109  days.setBit( startDate.dayOfWeek() - 1 );
110  r->addMonthlyPos( pos, days );
111  } else if ( rtype == "Yearly" ) {
112  r->setYearly( freq );
113  if ( hasEndDate )
114  r->setEndDate( endDate );
115  }
116  }
117 
118  TQString categoryList = attributes.value( "categories" );
119  event->setCategories( lookupCategories( categoryList ) );
120 
121  TQString alarmStr = attributes.value( "alarm" );
122  if ( !alarmStr.isEmpty() ) {
123  kdDebug(5800) << "Alarm: " << alarmStr << endl;
124  Alarm *alarm = new Alarm( event );
125  alarm->setType( Alarm::Display );
126  alarm->setEnabled( true );
127  int alarmOffset = alarmStr.toInt();
128  alarm->setStartOffset( alarmOffset * -60 );
129  event->addAlarm( alarm );
130  }
131 
132  Event *oldEvent = mCalendar->event( uid );
133  if ( oldEvent ) mCalendar->deleteEvent( oldEvent );
134 
135  mCalendar->addEvent( event );
136  } else if ( qName == "Task" ) {
137  Todo *todo = new Todo;
138 
139  TQString uid = "TQtopia" + attributes.value( "Uid" );
140  todo->setUid( uid );
141 
142  TQString description = attributes.value( "Description" );
143  int pos = description.find( '\n' );
144  if ( pos > 0 ) {
145  TQString summary = description.left( pos );
146  todo->setSummary( summary );
147  todo->setDescription( description );
148  } else {
149  todo->setSummary( description );
150  }
151 
152  int priority = attributes.value( "Priority" ).toInt();
153 // if ( priority == 0 ) priority = 3;
154  todo->setPriority( priority );
155 
156  TQString categoryList = attributes.value( "Categories" );
157  todo->setCategories( lookupCategories( categoryList ) );
158 
159  TQString completedStr = attributes.value( "Completed" );
160  if ( completedStr == "1" ) todo->setCompleted( true );
161 
162  TQString hasDateStr = attributes.value( "HasDate" );
163  if ( hasDateStr == "1" ) {
164  int year = attributes.value( "DateYear" ).toInt();
165  int month = attributes.value( "DateMonth" ).toInt();
166  int day = attributes.value( "DateDay" ).toInt();
167 
168  todo->setDtDue( TQDateTime( TQDate( year, month, day ) ) );
169  todo->setHasDueDate( true );
170  }
171 
172  Todo *oldTodo = mCalendar->todo( uid );
173  if ( oldTodo ) mCalendar->deleteTodo( oldTodo );
174 
175  mCalendar->addTodo( todo );
176  } else if ( qName == "Category" ) {
177  TQString id = attributes.value( "id" );
178  TQString name = attributes.value( "name" );
179  setCategory( id, name );
180  }
181 
182  return true;
183  }
184 
185  bool warning ( const TQXmlParseException &exception )
186  {
187  kdDebug(5800) << "WARNING" << endl;
188  printException( exception );
189  return true;
190  }
191 
192  bool error ( const TQXmlParseException &exception )
193  {
194  kdDebug(5800) << "ERROR" << endl;
195  printException( exception );
196  return false;
197  }
198 
199  bool fatalError ( const TQXmlParseException &exception )
200  {
201  kdDebug(5800) << "FATALERROR" << endl;
202  printException( exception );
203  return false;
204  }
205 
206  TQString errorString ()
207  {
208  return "TQtopiaParser: Error!";
209  }
210 
211  protected:
212  void printException( const TQXmlParseException &exception )
213  {
214  kdError() << "XML Parse Error (line " << exception.lineNumber()
215  << ", col " << exception.columnNumber() << "): "
216  << exception.message() << "(public ID: '"
217  << exception.publicId() << "' system ID: '"
218  << exception.systemId() << "')" << endl;
219  }
220 
221  TQDateTime toDateTime( const TQString &value )
222  {
223  TQDateTime dt;
224  dt.setTime_t( value.toUInt() );
225 
226  return dt;
227  }
228 
229  TQStringList lookupCategories( const TQString &categoryList )
230  {
231  TQStringList categoryIds = TQStringList::split( ";", categoryList );
232  TQStringList categories;
233  TQStringList::ConstIterator it;
234  for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) {
235  categories.append( category( *it ) );
236  }
237  return categories;
238  }
239 
240  private:
241  Calendar *mCalendar;
242 
243  static TQString category( const TQString &id )
244  {
245  TQMap<TQString,TQString>::ConstIterator it = mCategoriesMap.find( id );
246  if ( it == mCategoriesMap.end() ) return id;
247  else return *it;
248  }
249 
250  static void setCategory( const TQString &id, const TQString &name )
251  {
252  mCategoriesMap.insert( id, name );
253  }
254 
255  static TQMap<TQString,TQString> mCategoriesMap;
256 };
257 
258 TQMap<TQString,TQString> TQtopiaParser::mCategoriesMap;
259 
260 TQtopiaFormat::TQtopiaFormat()
261 {
262 }
263 
264 TQtopiaFormat::~TQtopiaFormat()
265 {
266 }
267 
268 bool TQtopiaFormat::load( Calendar *calendar, const TQString &fileName)
269 {
270  kdDebug(5800) << "TQtopiaFormat::load() " << fileName << endl;
271 
272  clearException();
273 
274  TQtopiaParser handler( calendar );
275  TQFile xmlFile( fileName );
276  TQXmlInputSource source( xmlFile );
277  TQXmlSimpleReader reader;
278  reader.setContentHandler( &handler );
279  return reader.parse( source );
280 }
281 
282 bool TQtopiaFormat::save( Calendar *calendar, const TQString &fileName )
283 {
284  kdDebug(5800) << "TQtopiaFormat::save(): " << fileName << endl;
285 
286  clearException();
287 
288  TQString text = toString( calendar );
289 
290  if ( text.isNull() ) return false;
291 
292  // TODO: write backup file
293 
294  TQFile file( fileName );
295  if (!file.open( IO_WriteOnly ) ) {
297  i18n("Could not open file '%1'").arg(fileName)));
298  return false;
299  }
300  TQTextStream ts( &file );
301  ts << text;
302  file.close();
303 
304  return true;
305 }
306 
307 bool TQtopiaFormat::fromString( Calendar *, const TQString & )
308 {
309  kdDebug(5800) << "TQtopiaFormat::fromString() not yet implemented." << endl;
310  return false;
311 }
312 
314 {
315  return TQString();
316 }
Provides the main "calendar" object class.
This class represents an alarm notification.
Definition: alarm.h:46
void setEnabled(bool enable)
Set the alarm enabled status.
Definition: alarm.cpp:432
void setStartOffset(const Duration &)
Set offset of alarm in time relative to the start of the event.
Definition: alarm.cpp:443
void setType(Type type)
Set the type of the alarm.
Definition: alarm.cpp:115
void setException(ErrorFormat *error)
Set exception for this object.
Definition: calformat.cpp:50
void clearException()
Clear exception status of this format object.
Definition: calformat.cpp:44
This is the main "calendar" object class.
Definition: calendar.h:171
Calendar format related error class.
Definition: exceptions.h:65
@ SaveError
Save error.
Definition: exceptions.h:72
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
void setUid(const TQString &)
Set the unique id for the event.
void setSummary(const TQString &summary)
Set short summary.
Definition: incidence.cpp:286
void setPriority(int priority)
Set the incidences priority.
Definition: incidence.cpp:729
void setDescription(const TQString &description)
Set the long description.
Definition: incidence.cpp:273
void setCategories(const TQStringList &categories)
Set categories.
Definition: incidence.cpp:298
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:90
void setYearly(int freq)
Sets an event to recur yearly.
Definition: recurrence.cpp:671
void setWeekly(int freq, int weekStart=1)
Sets an event to recur weekly.
Definition: recurrence.cpp:590
void setMonthly(int freq)
Sets an event to recur monthly.
Definition: recurrence.cpp:609
void addMonthlyPos(short pos, const TQBitArray &days)
Adds a position (e.g.
Definition: recurrence.cpp:615
void setDaily(int freq)
Sets an event to recur daily.
Definition: recurrence.cpp:584
void addMonthlyDate(short day)
Adds a date (e.g.
Definition: recurrence.cpp:657
void setEndDate(const TQDate &endDate)
Sets the date of the last recurrence.
Definition: recurrence.cpp:378
bool fromString(Calendar *, const TQString &)
Parse string and populate calendar with that information.
TQString toString(Calendar *)
Return calendar information as string.
bool save(Calendar *, const TQString &fileName)
writes out the calendar to disk.
bool load(Calendar *, const TQString &fileName)
loads a calendar on disk into the calendar associated with this format.
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
void setDtDue(const TQDateTime &dtDue, bool first=false)
Sets due date and time.
Definition: todo.cpp:85
void setCompleted(bool completed)
Set completed state.
Definition: todo.cpp:223
void setHasDueDate(bool hasDueDate)
Set if the todo has a due date.
Definition: todo.cpp:149
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38