kitchensync Library API Documentation

datebook.cpp

00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2002,2003 Holger Freyther <freyther@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include <qdom.h>
00023 #include <qfile.h>
00024 
00025 #include <kdebug.h>
00026 
00027 #include <calendarsyncee.h>
00028 #include <libkcal/calendarlocal.h>
00029 
00030 #include "device.h"
00031 #include "datebook.h"
00032 
00033 using namespace OpieHelper;
00034 
00035 namespace {
00036 // from TT
00037 int week ( const QDate &start ) {
00038     int stop = start.day();
00039     int sentinel = start.dayOfWeek();
00040     int dayOfWeek = QDate( start.year(),  start.month(),  1 ).dayOfWeek();
00041     int week = 1;
00042     for ( int i = 1; i < stop; i++ ) {
00043         if ( dayOfWeek++ == sentinel )
00044             week++;
00045         if ( dayOfWeek > 7 )
00046             dayOfWeek = 0;
00047     }
00048     return week;
00049 }
00050 
00051 }
00052 
00053 DateBook::DateBook( CategoryEdit* edit,
00054                     KSync::KonnectorUIDHelper* helper,
00055                     const QString& tz,
00056                     bool meta, Device *dev )
00057     : Base( edit,  helper,  tz, meta, dev )
00058 {
00059 }
00060 DateBook::~DateBook(){
00061 }
00065 KCal::Event* DateBook::toEvent( QDomElement e, ExtraMap& extraMap, const QStringList& lst) {
00066     KCal::Event* event = new KCal::Event();
00067     
00068     /* Category block */
00069     {
00070     QStringList list = QStringList::split(";",  e.attribute("categories") );
00071     QStringList categories;
00072 
00073     QString cat;
00074     for ( uint i = 0; i < list.count(); i++ ) {
00075         cat = m_edit->categoryById(list[i], "Calendar");
00076     /* only add if name not empty and was not added before */
00077         if (!cat.isEmpty() && !categories.contains(cat) )
00078             categories.append(cat );
00079     }
00080     if (!categories.isEmpty() ) {
00081         event->setCategories( categories );
00082     }
00083     
00084     }
00085 
00086     event->setSummary( e.attribute("description") );
00087     event->setUid( kdeId( "EventSyncEntry",  e.attribute("uid") ) );
00088     event->setDescription( e.attribute("note") );
00089     event->setLocation( e.attribute("location") );
00090     // time
00091 
00092     QString start = e.attribute("start");
00093     event->setDtStart( fromUTC( (time_t) start.toLong() ) );
00094 
00095     QString end = e.attribute("end");
00096     event->setDtEnd( fromUTC( (time_t) end.toLong() ) );
00097 
00098     // type
00099     if ( e.attribute("type") == "AllDay" ) {
00100         event->setFloats( true );
00101     }else{
00102         event->setFloats( false );
00103     }
00104 
00105     // FIXME alarm
00106 
00107 
00108     // Recurrence damn I feared to do that
00109     QString type = e.attribute("rtype");
00110     int freq = e.attribute("rfreq").toInt();
00111     bool hasEnd = e.attribute("rhasenddate").toInt();
00112     //kdDebug(5229) << "HasEndDate: " << hasEnd << endl;
00113 
00114     KCal::Recurrence *rec = event->recurrence();
00115     start = e.attribute("created");
00116     rec->setRecurStart( fromUTC( (time_t) start.toLong() ) );
00117 
00118     if ( type == "Daily" ) {
00119         if ( hasEnd ) {
00120             start = e.attribute("enddt");
00121             rec->setDaily(freq,  fromUTC( (time_t) start.toLong() ).date() );
00122         }else{
00123             rec->setDaily( freq,  -1 );
00124         }
00125         // weekly
00126     }else if ( type == "Weekly") {
00127         int days = e.attribute("rweekdays").toInt();
00128         QBitArray bits( 7 );
00129         bits.fill( false );
00130         if ( Monday & days )
00131             bits.setBit( 0 );
00132         if ( Tuesday & days )
00133             bits.setBit( 1 );
00134         if ( Wednesday & days )
00135             bits.setBit( 2 );
00136         if ( Thursday & days )
00137             bits.setBit( 3 );
00138         if ( Friday & days )
00139             bits.setBit( 4 );
00140         if ( Saturday & days )
00141             bits.setBit( 5 );
00142         if ( Sunday & days )
00143             bits.setBit( 6 );
00144 
00145         if ( hasEnd ) {
00146             start = e.attribute("enddt");
00147 //            kdDebug(5229) << "has end " << start << endl;
00148             rec->setWeekly( freq,  bits, fromUTC( (time_t) start.toLong() ).date() );
00149         }else{
00150             rec->setWeekly( freq,  bits,  -1 );
00151         }
00152     // monthly
00153     }else if ( type == "MonthlyDay" ) {
00154         // monthly day the  1st Saturday of the month
00155         int rposition = e.attribute("rposition").toInt();
00156         if ( hasEnd ) {
00157             start = e.attribute("enddt");
00158             rec->setMonthly( KCal::Recurrence::rMonthlyPos,
00159                              freq,fromUTC( (time_t) start.toLong() ).date() );
00160         }else{
00161             rec->setMonthly( KCal::Recurrence::rMonthlyPos,
00162                              freq,  -1 );
00163         }
00164         QBitArray array( 7);
00165         array.fill( false );
00166         QDate date = event->dtStart().date();
00167         array.setBit( date.dayOfWeek() - 1 );
00168         rec->addMonthlyPos( rposition, array );
00169 
00170     }else if ( type == "MonthlyDate" ) {
00171         // int rposition = e.attribute("rposition").toInt();
00172         if ( hasEnd ) {
00173             start = e.attribute("enddt");
00174             rec->setMonthly( KCal::Recurrence::rMonthlyDay,
00175                              freq,fromUTC( (time_t) start.toLong() ).date() );
00176         }else{
00177             rec->setMonthly( KCal::Recurrence::rMonthlyDay,
00178                              freq,  -1 );
00179         }
00180         QDate date = event->dtStart().date();
00181         rec->addMonthlyDay( date.day() );
00182 
00183     }else if ( type == "Yearly" ) {
00184         if (hasEnd ) {
00185             start = e.attribute("enddt");
00186             rec->setYearly( KCal::Recurrence::rYearlyDay,
00187                             freq,
00188                             fromUTC( (time_t) start.toLong() ).date() );
00189         }else{
00190             rec->setYearly( KCal::Recurrence::rYearlyDay,
00191                             freq, -1 );
00192         }
00193         rec->addYearlyNum( event->dtStart().date().dayOfYear() );
00194     }
00195 
00196     // now save the attributes for later use
00197     extraMap.add("datebook", e.attribute("uid"), e.attributes(), lst );
00198 
00199     return event;
00200 }
00201 
00202 bool DateBook::toKDE( const QString& fileName, ExtraMap& extraMap, KSync::CalendarSyncee *syncee )
00203 {
00204     syncee->setSource( "Opie");
00205     syncee->setIdentifier( "Opie" );
00206     if( device() )
00207     syncee->setSupports( device()->supports( Device::Calendar ) );
00208 
00209     QFile file( fileName );
00210     if ( !file.open( IO_ReadOnly ) ) {
00211         return false;
00212     }
00213     QDomDocument doc("mydocument");
00214     if ( !doc.setContent( &file ) ) {
00215         return false;
00216     }
00217 
00218     QDomElement docElem = doc.documentElement();
00219     QDomNode n = docElem.firstChild();
00220     QString dummy;
00221     QStringList attr = attributes();
00222     while (!n.isNull() ) {
00223         QDomElement el = n.toElement();
00224         if (!el.isNull() ) {
00225 
00226             if ( el.tagName() == "events") {
00227 
00228                 QDomNode no = el.firstChild();
00229                 while (!no.isNull() ) {
00230                     QDomElement e = no.toElement();
00231 
00232                     if (!e.isNull() ) {
00233                         if (e.tagName() == "event") {
00234                             KCal::Event* event = toEvent( e, extraMap, attr );
00235                             if (event != 0 ) {
00236                                 KSync::CalendarSyncEntry* entry;
00237                                 entry = new KSync::CalendarSyncEntry( event, syncee );
00238                                 syncee->addEntry( entry );
00239                             }
00240                         }
00241                     }
00242                     no = no.nextSibling();
00243                 }
00244             }
00245             n = n.nextSibling();
00246         }// n.isNULL
00247     }
00248 
00249     return true;
00250 }
00251 
00252 KTempFile* DateBook::fromKDE( KSync::CalendarSyncee* syncee, ExtraMap& extraMap )
00253 {
00254     m_kde2opie.clear();
00255     Kontainer::ValueList newIds = syncee->ids( "EventSyncEntry");
00256     Kontainer::ValueList::ConstIterator idIt;
00257     for ( idIt = newIds.begin(); idIt != newIds.end(); ++idIt ) {
00258         m_helper->addId("EventSyncEntry",  (*idIt).first(),  (*idIt).second() );
00259     }
00260     KTempFile* tempFile = file();
00261     if ( tempFile->textStream() ) {
00262         QTextStream *stream = tempFile->textStream();
00263         stream->setEncoding( QTextStream::UnicodeUTF8 );
00264         *stream <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
00265         *stream << "<!DOCTYPE DATEBOOK><DATEBOOK>" << endl;
00266         KSync::CalendarSyncEntry *entry;
00267         KCal::Event *event;
00268         *stream << "<events>" << endl;
00269         for ( entry = (KSync::CalendarSyncEntry*) syncee->firstEntry();
00270               entry != 0;
00271               entry = (KSync::CalendarSyncEntry*) syncee->nextEntry() )
00272         {
00273             event = dynamic_cast<KCal::Event*>( entry->incidence() );
00274             if ( !event )
00275               continue;
00276 
00277             *stream << event2string( event, extraMap ) << endl;
00278         }
00279         *stream << "</events>" << endl;
00280         *stream << "</DATEBOOK>" << endl;
00281 
00282     }
00283     if (m_helper )
00284         m_helper->replaceIds( "EventSyncEntry",  m_kde2opie );
00285 
00286     tempFile->close();
00287     return tempFile;
00288 }
00289 QString DateBook::event2string( KCal::Event *event, ExtraMap& map )
00290 {
00291     QString uid = konnectorId("EventSyncEntry", event->uid() );
00292     bool doesFloat = event->doesFloat();
00293     QString str;
00294     str.append( "<event ");
00295     str.append( "description=\"" +escape( event->summary() ) + "\" ");
00296     str.append( "location=\"" + escape( event->location() ) + "\" ");
00297     str.append( "categories=\"" +  categoriesToNumber( event->categories() ) + "\" ");
00298     str.append( "uid=\"" + uid  + "\" ");
00299     str.append( "start=\"" +startDate( event->dtStart(), doesFloat ) + "\" ");
00300     str.append( "end=\"" +  endDate( event->dtEnd(), doesFloat) + "\" ");
00301     str.append( "note=\"" + escape( event->description() ) + "\" "); //use escapeString copied from TT
00302     if ( doesFloat )
00303         str.append( "type=\"AllDay\" ");
00304     // recurrence
00305     KCal::Recurrence *rec = event->recurrence();
00306     if ( rec->doesRecur() ) {
00307         QString type;
00308         switch( rec->doesRecur() ) {
00309         case KCal::Recurrence::rDaily :{
00310             type = "Daily";
00311             break;
00312         }
00313         case KCal::Recurrence::rWeekly :{
00314             type = "Weekly";
00315             char day = 0; // signed
00316             QBitArray array = rec->days();
00317             if ( array.testBit(0 ) ) day |= Monday;
00318             if ( array.testBit(1 ) ) day |= Tuesday;
00319             if ( array.testBit(2 ) ) day |= Wednesday;
00320             if ( array.testBit(3 ) ) day |= Thursday;
00321             if ( array.testBit(4 ) ) day |= Friday;
00322             if ( array.testBit(5 ) ) day |= Saturday;
00323             if ( array.testBit(6 ) ) day |= Sunday;
00324 
00325             /* need to be > 0  we set the repeat day to the day where the event takes place*/
00326             if ( day < 0 ) {
00327                 switch( event->dtStart().date().dayOfWeek() ) {
00328                 case 1: // Monday
00329                     day = Monday;
00330                     break;
00331                 case 2: // Tuesday
00332                     day = Tuesday;
00333                     break;
00334                 case 3: // Wednesday
00335                     day = Wednesday;
00336                     break;
00337                 case 4: //  Thursday
00338                     day = Thursday;
00339                     break;
00340                 case 5: // Friday
00341                     day = Friday;
00342                     break;
00343                 case 6: // Staurday
00344                     day = Saturday;
00345                     break;
00346                 default:// should never happen
00347                 case 7: // Sunday
00348                     day = Sunday;
00349                     break;
00350                 }
00351 
00352             }
00353             str.append( "rweekdays=\"" + QString::number(static_cast<int> (day) ) + "\" ");
00354             break;
00355         }
00356         case KCal::Recurrence::rMonthlyPos :{
00357             int rpos = week( event->dtStart().date() );
00358             if ( rpos != 0 )
00359                 str.append( "rposition=\"" + QString::number(rpos)  + "\" ");
00360             type = "MonthlyDay";
00361             break;
00362         }
00363         case KCal::Recurrence::rMonthlyDay :{
00364             type = "MonthlyDate";
00365 
00366             break;
00367         }
00368         case KCal::Recurrence::rYearlyMonth: // fall through
00369         case KCal::Recurrence::rYearlyPos: // fall through Might be wrong though
00370         case KCal::Recurrence::rYearlyDay :{
00371             type = "Yearly";
00372             break;
00373         }
00374         case KCal::Recurrence::rNone : // fall through
00375         default :
00376             type = QString::null;
00377             break;
00378         }
00379         if (!type.isEmpty() ) {
00380             str.append( "rtype=\"" + type + "\" ");
00381             str.append( "rfreq=\"" + QString::number( rec->frequency() ) + "\" ");
00382             if ( rec->duration() == -1 || rec->duration() != 0 )
00383                 str.append( "rhasenddate=\"0\" ");
00384             else if ( rec->duration() == 0 ) {
00385                 str.append( "rhasenddate=\"1\" ");
00386                 str.append( "enddt=\"" + QString::number( toUTC(rec->endDate() ) ) + "\" ");
00387             }
00388             str.append( "created=\"" + QString::number( toUTC(rec->recurStart() ) ) + "\" ");
00389         }
00390     }
00391     // FIXME alarm
00392     str += map.toString( "datebook", uid );
00393     str.append( " />" );
00394     return str;
00395 }
00396 /*
00397  * A list of attributes we handle
00398  */
00399 QStringList DateBook::attributes()const{
00400     QStringList lst;
00401     lst << "description";
00402     lst << "location";
00403     lst << "categories";
00404     lst << "uid";
00405     lst << "start";
00406     lst << "end";
00407     lst << "note";
00408     lst << "type";
00409     lst << "rweekdays";
00410     lst << "rposition";
00411     lst << "rtype";
00412     lst << "rfreq";
00413     lst << "rhasenddate";
00414     lst << "enddt";
00415     lst << "created";
00416     /*
00417      * we need to handle Recurrence Exceptions
00418      * alarms, timezones later
00419      */
00420     return lst;
00421 }
00422 /*
00423  * Qtopia etwartet AllDay events in einer Zeitspanne von 00:00:00
00424  * bis 23:59:59... but in korg bdays are from 00:00:00 - 00:00:00 (
00425  * no time associated )
00426  * He'll help Qtopia here if it's an all day event we will produce
00427  * a better time...
00428  */
00429 QString DateBook::startDate( const QDateTime& _dt,  bool allDay ) {
00430     QDateTime dt = _dt;
00431     if (allDay )
00432         dt.setTime( QTime(0, 0, 0 ) );
00433 
00434     return QString::number( toUTC( dt ) );
00435 }
00436 QString DateBook::endDate( const QDateTime& _dt,  bool allDay ) {
00437     QDateTime dt = _dt;
00438     if (allDay )
00439         dt.setTime( QTime(23, 59, 59 ) );
00440 
00441     return QString::number( toUTC(dt ) );
00442 }
00443 
KDE Logo
This file is part of the documentation for kitchensync Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:41:41 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003