kpilot/lib

pilotDateEntry.cc

00001 /* KPilot
00002 **
00003 ** Copyright (C) 1998-2001 by Dan Pilone
00004 ** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 **
00006 ** This is a C++ wrapper for the Pilot's datebook structures.
00007 */
00008 
00009 /*
00010 ** This program is free software; you can redistribute it and/or modify
00011 ** it under the terms of the GNU Lesser General Public License as published by
00012 ** the Free Software Foundation; either version 2.1 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 ** GNU Lesser General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU Lesser General Public License
00021 ** along with this program in a file called COPYING; if not, write to
00022 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023 ** MA 02110-1301, USA.
00024 */
00025 
00026 /*
00027 ** Bug reports and questions can be sent to kde-pim@kde.org
00028 */
00029 
00030 #include "options.h"
00031 
00032 #include <stdlib.h>
00033 
00034 #include <qdatetime.h>
00035 #include <qregexp.h>
00036 
00037 #include <kglobal.h>
00038 #include <kdebug.h>
00039 
00040 #include "pilotDateEntry.h"
00041 
00042 PilotDateEntry::PilotDateEntry(struct AppointmentAppInfo &appInfo):PilotRecordBase(), fAppInfo(appInfo)
00043 {
00044     ::memset(&fAppointmentInfo, 0, sizeof(struct Appointment));
00045 }
00046 
00047 /* initialize the entry from another one. If rec==NULL, this constructor does the same as PilotDateEntry()
00048 */
00049 PilotDateEntry::PilotDateEntry(struct AppointmentAppInfo &appInfo, PilotRecord * rec) :
00050     PilotRecordBase(rec),
00051     fAppInfo(appInfo)
00052 {
00053     ::memset(&fAppointmentInfo, 0, sizeof(fAppointmentInfo));
00054     if (rec)
00055     {
00056         // Construct a fake pi_buffer for unpack_Appointment.
00057         // No ownership changes occur here.
00058         pi_buffer_t b = { (unsigned char *) rec->data(), rec->size(), rec->size() } ;
00059         unpack_Appointment(&fAppointmentInfo, &b, datebook_v1);
00060     }
00061     return;
00062 
00063 }
00064 
00065 void PilotDateEntry::_copyExceptions(const PilotDateEntry & e)
00066 {
00067     if (e.fAppointmentInfo.exceptions > 0)
00068     {
00069         size_t blocksize = e.fAppointmentInfo.exceptions *
00070             sizeof(struct tm);
00071 
00072         fAppointmentInfo.exception = (struct tm *)::malloc(blocksize);
00073 
00074         if (fAppointmentInfo.exception)
00075         {
00076             fAppointmentInfo.exceptions =
00077                 e.fAppointmentInfo.exceptions;
00078             ::memcpy(fAppointmentInfo.exception,
00079                 e.fAppointmentInfo.exception, blocksize);
00080         }
00081         else
00082         {
00083             kdError() << __FUNCTION__
00084                 << ": malloc() failed, exceptions not copied"
00085                 << endl;
00086             fAppointmentInfo.exceptions = 0;
00087         }
00088     }
00089     else
00090     {
00091         fAppointmentInfo.exceptions = 0;
00092         fAppointmentInfo.exception = 0L;
00093     }
00094 }
00095 
00096 
00097 PilotDateEntry::PilotDateEntry(const PilotDateEntry & e) :
00098     PilotRecordBase(e),
00099     fAppInfo(e.fAppInfo)
00100 {
00101     ::memcpy(&fAppointmentInfo, &e.fAppointmentInfo,
00102         sizeof(struct Appointment));
00103     // See operator = for explanation
00104     fAppointmentInfo.exception = 0L;
00105     fAppointmentInfo.description = 0L;
00106     fAppointmentInfo.note = 0L;
00107 
00108     _copyExceptions(e);
00109     setDescriptionP(e.fAppointmentInfo.description);
00110     setNoteP(e.fAppointmentInfo.note);
00111 }
00112 
00113 
00114 PilotDateEntry & PilotDateEntry::operator = (const PilotDateEntry & e)
00115 {
00116     if (this != &e)     // Pointer equality!
00117     {
00118         KPILOT_FREE(fAppointmentInfo.exception);
00119         KPILOT_FREE(fAppointmentInfo.description);
00120         KPILOT_FREE(fAppointmentInfo.note);
00121         ::memcpy(&fAppointmentInfo, &e.fAppointmentInfo,
00122             sizeof(fAppointmentInfo));
00123 
00124         // The original pointers were already freed; since we're now
00125         // got the pointers from the new structure and we're going
00126         // to use the standard set functions make sure that
00127         // we don't free() the copies-of-pointers from e, which
00128         // would be disastrous.
00129         //
00130         //
00131         fAppointmentInfo.exception = 0L;
00132         fAppointmentInfo.description = 0L;
00133         fAppointmentInfo.note = 0L;
00134 
00135         _copyExceptions(e);
00136         setDescriptionP(e.fAppointmentInfo.description);
00137         setNoteP(e.fAppointmentInfo.note);
00138     }
00139 
00140     return *this;
00141 }               // end of assignment operator
00142 
00143 
00144 QString PilotDateEntry::getTextRepresentation(bool richText)
00145 {
00146     QString text, tmp;
00147     QString par = richText?CSL1("<p>"):QString::null;
00148     QString ps = richText?CSL1("</p>"):CSL1("\n");
00149     QString br = richText?CSL1("<br/>"):CSL1("\n");
00150 
00151     // title + name
00152     text += par;
00153     tmp=richText?CSL1("<b><big>%1</big></b>"):CSL1("%1");
00154     text += tmp.arg(rtExpand(getDescription(), richText));
00155     text += ps;
00156 
00157     QDateTime dt(readTm(getEventStart()));
00158     QString startDate(dt.toString(Qt::LocalDate));
00159     text+=par;
00160     text+=i18n("Start date: %1").arg(startDate);
00161     text+=ps;
00162 
00163     if (isEvent())
00164     {
00165         text+=par;
00166         text+=i18n("Whole-day event");
00167         text+=ps;
00168     }
00169     else
00170     {
00171         dt=readTm(getEventEnd());
00172         QString endDate(dt.toString(Qt::LocalDate));
00173         text+=par;
00174         text+=i18n("End date: %1").arg(endDate);
00175         text+=ps;
00176     }
00177 
00178     if ( isAlarmEnabled() )
00179     {
00180         text+=par;
00181         tmp=i18n("%1 is the duration, %2 is the time unit", "Alarm: %1 %2 before event starts").
00182             arg(getAdvance());
00183         switch (getAdvanceUnits())
00184         {
00185             case advMinutes: tmp=tmp.arg(i18n("minutes")); break;
00186             case advHours: tmp=tmp.arg(i18n("hours")); break;
00187             case advDays: tmp=tmp.arg(i18n("days")); break;
00188             default: tmp=tmp.arg(QString::null); break;;
00189         }
00190         text+=tmp;
00191         text+=ps;
00192     }
00193 
00194     if (getRepeatType() != repeatNone)
00195     {
00196         text+=par;
00197         tmp=i18n("Recurrence: every %1 %2");
00198         int freq = getRepeatFrequency();
00199         tmp=tmp.arg(freq);
00200 
00201         switch(getRepeatType())
00202         {
00203             case repeatDaily: tmp=tmp.arg(i18n("day(s)")); break;
00204             case repeatWeekly: tmp=tmp.arg(i18n("week(s)")); break;
00205             case repeatMonthlyByDay:
00206             case repeatMonthlyByDate: tmp=tmp.arg(i18n("month(s)")); break;
00207             case repeatYearly: tmp=tmp.arg(i18n("year(s)")); break;
00208             default: tmp=tmp.arg(QString::null); break;
00209         }
00210         text+=tmp;
00211         text+=br;
00212 
00213         bool repeatsForever = getRepeatForever();
00214         if (repeatsForever)
00215         {
00216             text+=i18n("Repeats indefinitely");
00217         }
00218         else
00219         {
00220             dt = readTm(getRepeatEnd()).date();
00221             text+=i18n("Until %1").arg(dt.toString(Qt::LocalDate));
00222         }
00223         text+=br;
00224 
00225         if (getRepeatType()==repeatMonthlyByDay) text+=i18n("Repeating on the i-th day of week j")+br;
00226         if (getRepeatType()==repeatMonthlyByDate) text+=i18n("Repeating on the n-th day of the month")+br;
00227         // TODO: show the dayArray when repeating weekly
00228         /*QBitArray dayArray(7);
00229         if (getRepeatType()==repeatWeekly) text+=i18n("Repeat day flags: %1").arg(getRepeatDays
00230         const int *days = dateEntry->getRepeatDays();
00231         // Rotate the days of the week, since day numbers on the Pilot and
00232         // in vCal / Events are different.
00233         if (days[0]) dayArray.setBit(6);
00234         for (int i = 1; i < 7; i++)
00235         {
00236             if (days[i]) dayArray.setBit(i-1);
00237         }*/
00238         text+=ps;
00239     }
00240 
00241     if (getExceptionCount()>0 )
00242     {
00243         text+=par;
00244         text+=i18n("Exceptions:")+br;
00245         for (int i = 0; i < getExceptionCount(); i++)
00246         {
00247             QDate exdt=readTm(getExceptions()[i]).date();
00248             text+=exdt.toString(Qt::LocalDate);
00249             text+=br;
00250         }
00251         text+=ps;
00252     }
00253 
00254     if (!getNote().isEmpty())
00255     {
00256         text += richText?CSL1("<hr/>"):CSL1("-------------------------\n");
00257         text+=par;
00258         text+=richText?i18n("<b><em>Note:</em></b><br>"):i18n("Note:\n");
00259         text+=rtExpand(getNote(), richText);
00260         text+=ps;
00261     }
00262 
00263     return text;
00264 }
00265 
00266 QDateTime PilotDateEntry::dtStart() const
00267 {
00268     FUNCTIONSETUP;
00269     return readTm( getEventStart() );
00270 }
00271 
00272 QDateTime PilotDateEntry::dtEnd() const
00273 {
00274     FUNCTIONSETUP;
00275     return readTm( getEventEnd() );
00276 }
00277 
00278 QDateTime PilotDateEntry::dtRepeatEnd() const
00279 {
00280     FUNCTIONSETUP;
00281     return readTm( getRepeatEnd() );
00282 }
00283 
00284 unsigned int PilotDateEntry::alarmLeadTime() const
00285 {
00286     FUNCTIONSETUP;
00287     if (!isAlarmEnabled()) return 0;
00288 
00289     int adv = getAdvance();
00290     if ( adv < 0 )
00291     {
00292         return 0; // Not possible to enter on the pilot
00293     }
00294     unsigned int t = adv;
00295     int u = getAdvanceUnits();
00296 
00297 
00298     switch(u)
00299     {
00300     case advMinutes : t *= 60; break;
00301     case advHours : t *= 3600; break;
00302     case advDays : t *= 3600 * 24; break;
00303     default: t = 0;
00304     }
00305 
00306     return t;
00307 }
00308 
00309 PilotRecord *PilotDateEntry::pack() const
00310 {
00311     int i;
00312 
00313     pi_buffer_t *b = pi_buffer_new( sizeof(fAppointmentInfo) );
00314     i = pack_Appointment(const_cast<Appointment_t *>(&fAppointmentInfo), b, datebook_v1);
00315     if (i<0)
00316     {
00317         // Generic error from the pack_*() functions.
00318         return 0;
00319     }
00320 
00321     // pack_Appointment sets b->used
00322     return new PilotRecord( b, this );
00323 }
00324 
00325 /* setExceptions sets a new set of exceptions. Note that
00326     PilotDateEntry assumes ownership of the array and will
00327     delete the old one. */
00328 void PilotDateEntry::setExceptions(struct tm *e) {
00329     if (fAppointmentInfo.exception != e)
00330     {
00331         KPILOT_FREE(fAppointmentInfo.exception);
00332     }
00333     fAppointmentInfo.exception=e;
00334 }
00335 
00336 
00337 void PilotDateEntry::setDescriptionP(const char *desc, int l)
00338 {
00339     FUNCTIONSETUP;
00340     KPILOT_FREE(fAppointmentInfo.description);
00341 
00342     if (desc && *desc)
00343     {
00344         if (-1 == l) l=::strlen(desc);
00345         fAppointmentInfo.description =
00346             (char *) ::malloc(l + 1);
00347         if (fAppointmentInfo.description)
00348         {
00349             strlcpy(fAppointmentInfo.description, desc, l+1);
00350         }
00351         else
00352         {
00353             kdError() << __FUNCTION__
00354                 << ": malloc() failed, description not set"
00355                 << endl;
00356         }
00357     }
00358     else
00359     {
00360         fAppointmentInfo.description = 0L;
00361     }
00362 }
00363 
00364 void PilotDateEntry::setNoteP(const char *note, int l)
00365 {
00366     FUNCTIONSETUP;
00367     KPILOT_FREE(fAppointmentInfo.note);
00368 
00369     if (note && *note)
00370     {
00371         if (-1 == l) l=::strlen(note);
00372         fAppointmentInfo.note = (char *)::malloc(l + 1);
00373         if (fAppointmentInfo.note)
00374         {
00375             strlcpy(fAppointmentInfo.note, note,l+1);
00376         }
00377         else
00378         {
00379             kdError() << __FUNCTION__
00380                 << ": malloc() failed, note not set" << endl;
00381         }
00382     }
00383     else
00384     {
00385         fAppointmentInfo.note = 0L;
00386     }
00387 }
00388 
00389 void PilotDateEntry::setNote(const QString &s)
00390 {
00391     QCString t = Pilot::toPilot(s);
00392     setNoteP( t.data(),t.length() );
00393 }
00394 
00395 void PilotDateEntry::setLocation(const QString &s)
00396 {
00397     QString note = Pilot::fromPilot(getNoteP());
00398     QRegExp rxp = QRegExp("^[Ll]ocation:[^\n]+\n");
00399 
00400     if( s.isNull() )
00401     {
00402         note.replace(rxp,"");
00403     }
00404     else
00405     {
00406         QString location = "Location: " + s + "\n";
00407         int pos = note.find(rxp);
00408 
00409         if(pos >= 0)
00410         {
00411             note.replace( rxp, location );
00412         }
00413         else
00414         {
00415             note = location + note;
00416             setNote( note );
00417         }
00418     }
00419 }
00420 
00421 QString PilotDateEntry::getLocation() const
00422 {
00423     // Read the complete note here and not the filtered
00424     // one from PilotDateEntry::getNote();
00425     QString note = Pilot::fromPilot(getNoteP());
00426     QRegExp rxp = QRegExp("^[Ll]ocation:[^\n]+\n");
00427     int pos = note.find(rxp, 0);
00428 
00429     if(pos >= 0)
00430     {
00431         QString location = rxp.capturedTexts().first();
00432         rxp = QRegExp("^[Ll]ocation:[\\s|\t]*");
00433         location.replace(rxp,"");
00434         location.replace("\n", "");
00435         return location;
00436     }
00437     else
00438     {
00439         return "";
00440     }
00441 }
00442 
00443 void PilotDateEntry::setDescription(const QString &s)
00444 {
00445     QCString t = Pilot::toPilot(s);
00446     setDescriptionP( t.data(),t.length() );
00447 }
00448 
00449 QString PilotDateEntry::getNote() const
00450 {
00451     QString note = Pilot::fromPilot(getNoteP());
00452     QRegExp rxp = QRegExp("^[Ll]ocation:[^\n]+\n");
00453     note.replace(rxp, "" );
00454     return note;
00455 }
00456 
00457 QString PilotDateEntry::getDescription() const
00458 {
00459     return Pilot::fromPilot(getDescriptionP());
00460 }
00461 
KDE Home | KDE Accessibility Home | Description of Access Keys