kitchensync

todo.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., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <qfile.h>
00023 
00024 #include <klocale.h>
00025 
00026 #include <calendarsyncee.h>
00027 #include <idhelper.h>
00028 #include <libkcal/calendarlocal.h>
00029 
00030 #include "device.h"
00031 #include "todo.h"
00032 
00033 using namespace OpieHelper;
00034 
00035 
00036 ToDo::ToDo( CategoryEdit* edit,
00037             KSync::KonnectorUIDHelper* helper,
00038             const QString &tz,
00039             Device* dev)
00040     : Base( edit,  helper,  tz, dev )
00041 {
00042 }
00043 ToDo::~ToDo(){
00044 }
00045 
00046 KCal::Todo* ToDo::dom2todo( QDomElement e, ExtraMap& extra,const QStringList& lst ) {
00047     QString dummy;
00048     int Int;
00049     KCal::Todo* todo = new KCal::Todo();
00050     QStringList list = QStringList::split(";",  e.attribute("Categories") );
00051     QStringList categories;
00052 
00053     QString cat;
00054     for ( uint i = 0; i < list.count(); i++ ) {
00055         cat = m_edit->categoryById( list[i], "Todo List");
00056     /* only if cat is not empty and not already added */
00057         if (!cat.isEmpty() && !categories.contains( cat) )
00058             categories.append(cat );
00059     }
00060     if (!categories.isEmpty() ) {
00061         todo->setCategories( categories );
00062     }
00063 
00064     todo->setDescription(e.attribute("Description" ) );
00065     todo->setSummary( e.attribute("Summary") ); //opie only
00066     if ( ( device() && device()->distribution() == Device::Zaurus ) || todo->summary().isEmpty() )
00067         todo->setSummary( e.attribute("Description").stripWhiteSpace().left(20).simplifyWhiteSpace() );
00068 
00069     setUid(todo,  e.attribute("Uid")  );
00070 
00071     dummy = e.attribute("Completed");
00072 
00073     QDate comp = e.hasAttribute( "CompletedDate" ) ?
00074                  stringToDate( e.attribute( "CompletedDate" ) ):
00075                  QDate();
00076 
00077     /*
00078      * if setCompleted is called
00079      * libkcal decides to put
00080      * percentage done to 100%
00081      * but if I put percentage
00082      * to say 50% it is not uncompleting the item
00083      * and if setCompleted( false ) is called
00084      * likcal sets percent completed to 0
00085      */
00086     Int = dummy.toInt();
00087 
00088 
00089     /* !0 */
00090     if ( !Int ) {
00091         todo->setCompleted( false );
00092 
00093         /*
00094          * libkcal wants to be too smart again
00095          * 100% percent done but not completed
00096          * will be marked as completed...
00097          * So let us save the completion status
00098          * and apply it on writeback
00099          */
00100         int prog =  e.attribute("Progress").toInt();
00101         todo->setPercentComplete( prog );
00102         extra.add("todo", "CompletionItem", e.attribute("Uid"),
00103                   new TodoExtraItem( Int, prog ) );
00104     }else {
00105       if ( comp.isValid() )
00106         todo->setCompleted( comp );
00107       else
00108         todo->setCompleted(true );
00109     }
00110 
00111 
00112 
00113 
00114     dummy = e.attribute("Priority" );
00115     todo->setPriority(dummy.toInt( )  );
00116 
00117 
00118     dummy = e.attribute("HasDate" );
00119     bool status = dummy.toInt( );
00120     if(status){
00121         todo->setHasDueDate(true );
00122         QDateTime time = QDateTime::currentDateTime();
00123         QDate date;
00124 
00125 
00126         dummy = e.attribute("DateDay" );
00127         int day= dummy.toInt( );
00128         int month = e.attribute("DateMonth").toInt( );
00129         int year = e.attribute("DateYear").toInt( );
00130         date.setYMD(year, month, day);
00131         time.setDate( date );
00132         todo->setDtDue( time );
00133 
00134         /*
00135          * libkcal does not set HasDueDate TRUE
00136          * if we supply a due date
00137          */
00138         todo->setHasDueDate( true );
00139     }else{
00140         todo->setHasDueDate( false );
00141     }
00142 
00143     if ( e.hasAttribute( "StartDate" ) ) {
00144       todo->setHasStartDate( true );
00145       todo->setDtStart( stringToDate(e.attribute( "StartDate")) );
00146     }
00147 
00148     // time to add extra not used attributes
00149     extra.add("todo", e.attribute("Uid"),  e.attributes(), lst );
00150 
00151     return todo;
00152 }
00153 
00154 bool ToDo::toKDE( const QString &fileName, ExtraMap& map, KSync::CalendarSyncee *syncee )
00155 {
00156   QFile file( fileName );
00157   if ( !file.open( IO_ReadOnly ) ) {
00158     return false;
00159   }
00160 
00161   QDomDocument doc( "mydocument" );
00162   if ( !doc.setContent( &file ) ) {
00163     return false;
00164   }
00165 
00166   QStringList attr = supportedAttributes();
00167   QDomElement docElem = doc.documentElement();
00168   KCal::Todo *todo;
00169   QDomNode n = docElem.firstChild();
00170   while ( !n.isNull() ) {
00171     QDomElement e = n.toElement();
00172     if ( !e.isNull() ) {
00173       if ( e.tagName() == "Task" ) {
00174         todo = dom2todo( e, map,attr );
00175         KSync::CalendarSyncEntry* entry;
00176         entry = new KSync::CalendarSyncEntry( todo, syncee );
00177         syncee->addEntry( entry );
00178       }
00179     }
00180 
00181     n = n.nextSibling();
00182   }
00183 
00184   return true;
00185 }
00186 
00187 KTempFile* ToDo::fromKDE( KSync::CalendarSyncee* syncee, ExtraMap& map )
00188 {
00189     // KDE ID clear bit first
00190     m_kde2opie.clear();
00191     Kontainer::ValueList newIds = syncee->ids( "TodoSyncEntry");
00192     for ( Kontainer::ValueList::ConstIterator idIt = newIds.begin(); idIt != newIds.end(); ++idIt ) {
00193         m_helper->addId("TodoSyncEntry",  (*idIt).first,  (*idIt).second );
00194     }
00195     // update m_helper first;
00196     KTempFile* tmpFile = file();
00197     if (tmpFile->textStream() ) {
00198         // clear list
00199         KSync::CalendarSyncEntry* entry;
00200         QTextStream *stream = tmpFile->textStream();
00201         stream->setEncoding( QTextStream::UnicodeUTF8 );
00202         *stream << "<!DOCTYPE Tasks>" << endl;
00203         *stream << "<Tasks>" << endl;
00204         for ( entry = (KSync::CalendarSyncEntry*)syncee->firstEntry();
00205               entry != 0l;
00206               entry = (KSync::CalendarSyncEntry*)syncee->nextEntry() )
00207         {
00208             if ( entry->wasRemoved() )
00209                 continue;
00210 
00211             KCal::Todo *todo = dynamic_cast<KCal::Todo*>( entry->incidence() );
00212             if ( !todo )
00213               continue;
00214 
00215             *stream << todo2String( todo, map ) << endl;
00216         }
00217         *stream << "</Tasks>" << endl;
00218     }
00219     if (m_helper)
00220         m_helper->replaceIds( "TodoSyncEntry",  m_kde2opie );
00221 
00222     tmpFile->close();
00223 
00224     return tmpFile;
00225 }
00226 void ToDo::setUid( KCal::Todo* todo,  const QString &uid )
00227 {
00228     todo->setUid( kdeId( "TodoSyncEntry",  uid ) );
00229 }
00230 
00231 QString ToDo::todo2String( KCal::Todo* todo, ExtraMap& map )
00232 {
00233   // id hacking We don't want to have the ids growing and growing
00234   // when an id is used again it will be put to the used list and after done
00235   // with syncing we will replace the former
00236   QString uid = konnectorId("TodoSyncEntry", todo->uid() );
00237 
00238   QString text;
00239     text.append("<Task ");
00240     QStringList list = todo->categories();
00241     text.append( appendText( "Categories=\"" +
00242                              categoriesToNumber( list ) + "\" ",
00243                              "Categories=\"\" " ) );
00244 
00245     {
00246       bool comp     = todo->isCompleted();
00247       int completed = todo->percentComplete();
00248 
00249       if ( completed == 100 ) {
00250         TodoExtraItem *item = static_cast<TodoExtraItem*>(
00251                               map.item( "todo", "CompletionItem",
00252                                         uid ) );
00253         comp = (item &&item->completion==100) ? item->completed : comp;
00254       }
00255 
00256       text.append( "Completed=\""+QString::number(comp) + "\" " );
00257       text.append( "Progress=\"" + QString::number(completed) + "\" ");
00258 
00259       if ( comp && todo->hasCompletedDate() )
00260         text.append( "CompletedDate=\"" +
00261                      dateToString( todo->completed().date() ) + "\" ");
00262     }
00263 
00264     /* if it is not a Stock Zaurus we will right the summary */
00265     if ( device() && device()->distribution() != Device::Zaurus )
00266         text.append( appendText( "Summary=\"" +escape( todo->summary() )+"\" ",
00267                                  "Summary=\"\" "));
00268 
00269     if ( todo->hasDueDate() ) {
00270         text.append( "HasDate=\"1\" ");
00271         QDateTime time = todo->dtDue();
00272         text.append( "DateDay=\"" +QString::number( time.date().day() ) + "\" ");
00273         text.append( "DateMonth=\"" + QString::number( time.date().month() ) + "\" " );
00274         text.append( "DateYear=\"" + QString::number( time.date().year() )+ "\" " );
00275     }else{
00276         text.append( "HasDate=\"0\" ");
00277     }
00278     text.append( "Priority=\"" + QString::number( todo->priority() ) +"\" " );
00279 
00280     /* if Opie let's write the description right away
00281      * else we need to find out if description is empty and then
00282      * fallback to the summary if both are empty you're lost!
00283      **/
00284     if ( device() && device()->distribution() != Device::Zaurus )
00285         text.append( appendText("Description=\"" +escape( todo->description() ) + "\" ",
00286                                 "Description=\"\" " ) );
00287     else{
00288         QString desc = todo->description().isEmpty() ?
00289                        todo->summary() : todo->description();
00290         text.append( appendText("Description=\"" +escape( desc ) + "\" ",
00291                                 "Description=\"\" " ));
00292     }
00293 
00294     if ( todo->hasStartDate() )
00295       text.append( "StartDate=\"" + dateToString( todo->dtStart().date() )
00296                    + "\" " );
00297 
00298 
00299     text.append("Uid=\"" +uid + "\" "  );
00300 
00301     /* add custom entries */
00302     text.append( map.toString("todo", uid ) );
00303 
00304     text.append(" />");
00305     return text;
00306 }
00307 
00308 QStringList ToDo::supportedAttributes() {
00309     QStringList lst;
00310     lst << "Categories";
00311     lst << "Completed";
00312     lst << "Progress";
00313     lst << "Summary";
00314     lst << "HasDate";
00315     lst << "DateDay";
00316     lst << "DateMonth";
00317     lst << "DateYear";
00318     lst << "Priority";
00319     lst << "Description";
00320     lst << "Uid";
00321     lst << "StartDate";
00322     lst << "CompletedDate";
00323 
00324     return lst;
00325 }
00326 
00327 QString  ToDo::dateToString( const QDate& date  ) {
00328   return date.toString( "yyyyMMdd" );
00329 }
00330 
00331 QDate    ToDo::stringToDate( const QString& s ) {
00332   // From OPimDateConversion
00333   // Read ISO-Format (YYYYMMDD)
00334   int year = s.mid( 0, 4 ).toInt();
00335   int month = s.mid( 4, 2 ).toInt();
00336   int day = s.mid( 6, 2 ).toInt();
00337 
00338   QDate date;
00339   date.setYMD( year, month, day );
00340 
00341   return date;
00342 }
KDE Home | KDE Accessibility Home | Description of Access Keys