summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro14
-rw-r--r--libopie/orecurrancewidget.cpp2
-rw-r--r--libopie/pim/ocontactaccessbackend_vcard.cpp11
-rw-r--r--libopie/pim/oevent.cpp427
-rw-r--r--libopie/pim/oevent.h198
-rw-r--r--libopie/pim/orecur.cpp25
-rw-r--r--libopie/pim/orecur.h12
-rw-r--r--libopie/pim/otimezone.cpp104
-rw-r--r--libopie/pim/otimezone.h71
-rw-r--r--libopie/pim/otodo.cpp2
-rw-r--r--libopie/pim/test/oevent_test.cpp23
-rw-r--r--libopie/pim/test/oevent_test.pro11
-rw-r--r--libopie/pim/test/test_todo.cpp36
-rw-r--r--libopie/pim/test/todo_test.pro11
-rw-r--r--libopie/tododb.cpp268
-rw-r--r--libopie/tododb.h46
-rw-r--r--libopie/todoevent.cpp339
-rw-r--r--libopie/todoevent.h191
-rw-r--r--libopie/todoresource.h14
-rw-r--r--libopie/todovcalresource.cpp158
-rw-r--r--libopie/todovcalresource.h42
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp11
-rw-r--r--libopie2/opiepim/core/orecur.cpp25
-rw-r--r--libopie2/opiepim/core/orecur.h12
-rw-r--r--libopie2/opiepim/core/otimezone.cpp104
-rw-r--r--libopie2/opiepim/core/otimezone.h71
-rw-r--r--libopie2/opiepim/oevent.cpp427
-rw-r--r--libopie2/opiepim/oevent.h198
-rw-r--r--libopie2/opiepim/otodo.cpp2
29 files changed, 1751 insertions, 1104 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 675e1fa..2b843c1 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -1,108 +1,112 @@
TEMPLATE = lib
CONFIG += qte warn_on release
HEADERS = ofontmenu.h \
ocolorbutton.h \
- ofiledialog.h ofileselector.h tododb.h \
- ocheckitem.h todoevent.h todoresource.h \
- todovcalresource.h xmltree.h \
+ ofiledialog.h ofileselector.h \
+ ocheckitem.h \
+ xmltree.h \
colordialog.h colorpopupmenu.h \
oclickablelabel.h oprocctrl.h \
oprocess.h odevice.h odevicebutton.h \
otimepicker.h otabwidget.h \
otabbar.h otabinfo.h \
ofontselector.h \
pim/opimrecord.h \
pim/otodo.h \
pim/orecordlist.h \
pim/opimaccesstemplate.h \
pim/opimaccessbackend.h \
pim/otodoaccess.h \
pim/otodoaccessbackend.h \
pim/ocontact.h \
pim/ocontactaccess.h \
pim/ocontactaccessbackend.h \
pim/ocontactaccessbackend_xml.h \
pim/ocontactaccessbackend_vcard.h \
pim/obackendfactory.h \
pim/opimcache.h \
pim/otodoaccessvcal.h \
pim/orecur.h \
pim/opimstate.h \
pim/opimxrefpartner.h \
pim/opimxref.h \
pim/opimxrefmanager.h \
pim/opimmaintainer.h \
pim/opimnotify.h \
pim/opimnotifymanager.h \
pim/opimmainwindow.h \
pim/opimresolver.h \
+ pim/oevent.h \
+ pim/otimezone.h \
orecurrancewidget.h \
oticker.h
# pim/otodoaccesssql.h \
SOURCES = ofontmenu.cc \
ocolorbutton.cpp \
sharp_compat.cpp \
xmltree.cc \
ofiledialog.cc ofileselector.cc \
- ocheckitem.cpp tododb.cpp todoevent.cpp \
- todovcalresource.cpp colordialog.cpp \
+ ocheckitem.cpp \
+ colordialog.cpp \
colorpopupmenu.cpp oclickablelabel.cpp \
oprocctrl.cpp oprocess.cpp \
odevice.cpp odevicebutton.cpp otimepicker.cpp \
otabwidget.cpp otabbar.cpp \
ofontselector.cpp \
pim/otodo.cpp \
pim/opimrecord.cpp \
pim/otodoaccess.cpp \
pim/otodoaccessbackend.cpp \
pim/otodoaccessxml.cpp \
pim/ocontact.cpp \
pim/ocontactaccess.cpp \
pim/ocontactaccessbackend_vcard.cpp \
pim/otodoaccessvcal.cpp \
pim/orecur.cpp \
pim/opimstate.cpp \
pim/opimxrefpartner.cpp \
pim/opimxref.cpp \
pim/opimxrefmanager.cpp \
pim/opimmaintainer.cpp \
pim/opimnotify.cpp \
pim/opimnotifymanager.cpp \
pim/opimmainwindow.cpp \
pim/opimresolver.cpp \
+ pim/oevent.cpp \
+ pim/otimezone.cpp \
orecurrancewidget.cpp \
oticker.cpp
# pim/otodoaccesssql.cpp \
TARGET = opie
INCLUDEPATH += $(OPIEDIR)/include
DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
#VERSION = 1.0.0
LIBS += -lqpe
# LIBS += -lopiesql
INTERFACES = otimepickerbase.ui orecurrancebase.ui
TRANSLATIONS = ../i18n/de/libopie.ts \
../i18n/xx/libopie.ts \
../i18n/en/libopie.ts \
../i18n/es/libopie.ts \
../i18n/fr/libopie.ts \
../i18n/hu/libopie.ts \
../i18n/ja/libopie.ts \
../i18n/ko/libopie.ts \
../i18n/no/libopie.ts \
../i18n/pl/libopie.ts \
../i18n/pt/libopie.ts \
../i18n/pt_BR/libopie.ts \
../i18n/sl/libopie.ts \
../i18n/zh_CN/libopie.ts \
../i18n/zh_TW/libopie.ts \
../i18n/da/libopie.ts
include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/orecurrancewidget.cpp b/libopie/orecurrancewidget.cpp
index 0484ab9..db86184 100644
--- a/libopie/orecurrancewidget.cpp
+++ b/libopie/orecurrancewidget.cpp
@@ -1,564 +1,564 @@
#include <qapplication.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qspinbox.h>
#include <qpe/timestring.h>
#include "orecurrancewidget.h"
// Global Templates for use in setting up the repeat label...
const QString strDayTemplate = QObject::tr("Every");
const QString strYearTemplate = QObject::tr("%1 %2 every ");
const QString strMonthDateTemplate = QObject::tr("The %1 every ");
const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
const QString strWeekTemplate = QObject::tr("Every ");
const QString dayLabel[] = { QObject::tr("Monday"),
QObject::tr("Tuesday"),
QObject::tr("Wednesday"),
QObject::tr("Thursday"),
QObject::tr("Friday"),
QObject::tr("Saturday"),
QObject::tr("Sunday") };
static QString numberPlacing( int x ); // return the proper word format for
// x (1st, 2nd, etc)
static int week( const QDate &dt ); // what week in the month is dt?
ORecurranceWidget::ORecurranceWidget( bool startOnMonday,
const QDate& newStart,
QWidget* parent,
const char* name,
bool modal,
WFlags fl )
: ORecurranceBase( parent, name, modal, fl ),
start( newStart ),
currInterval( None ),
startWeekOnMonday( startOnMonday )
{
init();
fraType->setButton( currInterval );
chkNoEnd->setChecked( TRUE );
setupNone();
}
ORecurranceWidget::ORecurranceWidget( bool startOnMonday,
const ORecur& rp, const QDate& startDate,
QWidget* parent, const char* name,
bool modal, WFlags fl)
: ORecurranceBase( parent, name, modal, fl ),
start( startDate ),
end( rp.endDate() ),
startWeekOnMonday( startOnMonday )
{
// do some stuff with the repeat pattern
init();
setRecurrence( rp );
}
ORecurranceWidget::~ORecurranceWidget() {
}
void ORecurranceWidget::setStartDate( const QDate& date ) {
qWarning("ORecurranceWidget::setStartDate");
setRecurrence( recurrence(), date );
}
void ORecurranceWidget::setRecurrence( const ORecur& rp ) {
setRecurrence( rp, start );
}
void ORecurranceWidget::setRecurrence( const ORecur& rp, const QDate& date ) {
start = date;
end = rp.endDate();
switch ( rp.type() ) {
default:
case ORecur::NoRepeat:
currInterval = None;
setupNone();
break;
case ORecur::Daily:
currInterval = Day;
setupDaily();
break;
case ORecur::Weekly:
currInterval = Week;
setupWeekly();
int day, buttons;
for ( day = 0x01, buttons = 0; buttons < 7;
day = day << 1, buttons++ ) {
if ( rp.days() & day ) {
if ( startWeekOnMonday )
fraExtra->setButton( buttons );
else {
if ( buttons == 7 )
fraExtra->setButton( 0 );
else
fraExtra->setButton( buttons + 1 );
}
}
}
slotWeekLabel();
break;
case ORecur::MonthlyDay:
currInterval = Month;
setupMonthly();
fraExtra->setButton( 0 );
slotMonthLabel( 0 );
break;
case ORecur::MonthlyDate:
currInterval = Month;
setupMonthly();
fraExtra->setButton( 1 );
slotMonthLabel( 1 );
break;
case ORecur::Yearly:
currInterval = Year;
setupYearly();
break;
}
fraType->setButton( currInterval );
spinFreq->setValue( rp.frequency() );
if ( !rp.hasEndDate() ) {
cmdEnd->setText( tr("No End Date") );
chkNoEnd->setChecked( TRUE );
} else
cmdEnd->setText( TimeString::shortDate( end ) );
}
ORecur ORecurranceWidget::recurrence()const {
QListIterator<QToolButton> it( listRTypeButtons );
QListIterator<QToolButton> itExtra( listExtra );
ORecur rpTmp;
int i;
for ( i = 0; *it; ++it, i++ ) {
if ( (*it)->isOn() ) {
switch ( i ) {
case None:
rpTmp.setType( ORecur::NoRepeat );
break;
case Day:
rpTmp.setType( ORecur::Daily );
break;
case Week:{
rpTmp.setType( ORecur::Weekly );
int day;
int day2 = 0;
for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
if ( (*itExtra)->isOn() ) {
if ( startWeekOnMonday )
day2 |= day;
else {
if ( day == 1 )
day2 |= Event::SUN;
else
day2 |= day >> 1;
}
}
}
rpTmp.setDays( day2 );
}
break;
case Month:
if ( cmdExtra1->isOn() )
rpTmp.setType( ORecur::MonthlyDay );
else if ( cmdExtra2->isOn() )
rpTmp.setType( ORecur::MonthlyDate );
// figure out the montly day...
rpTmp.setPosition( week( start ) );
break;
case Year:
rpTmp.setType( ORecur::Yearly );
break;
}
break; // no need to keep looking!
}
}
rpTmp.setFrequency(spinFreq->value() );
rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
if ( rpTmp.hasEndDate() ) {
rpTmp.setEndDate( end );
}
// timestamp it...
- rpTmp.setCreateTime( time( NULL ) );
+// rpTmp.setCreateTime( ); current DateTime is already set -zecke
return rpTmp;
}
QDate ORecurranceWidget::endDate()const {
return end;
}
void ORecurranceWidget::slotSetRType(int rtype) {
// now call the right function based on the type...
currInterval = static_cast<repeatButtons>(rtype);
switch ( currInterval ) {
case None:
setupNone();
break;
case Day:
setupDaily();
break;
case Week:
setupWeekly();
slotWeekLabel();
break;
case Month:
setupMonthly();
cmdExtra2->setOn( TRUE );
slotMonthLabel( 1 );
break;
case Year:
setupYearly();
break;
}
}
void ORecurranceWidget::endDateChanged(int y, int m, int d) {
end.setYMD( y, m, d );
if ( end < start )
end = start;
cmdEnd->setText( TimeString::shortDate( end ) );
repeatPicker->setDate( end.year(), end.month(), end.day() );
}
void ORecurranceWidget::slotNoEnd( bool unused) {
// if the item was toggled, then go ahead and set it to the maximum date
if ( unused ) {
end.setYMD( 3000, 12, 31 );
cmdEnd->setText( tr("No End Date") );
} else {
end = start;
cmdEnd->setText( TimeString::shortDate(end) );
}
}
void ORecurranceWidget::setupRepeatLabel( const QString& s) {
lblVar1->setText( s );
}
void ORecurranceWidget::setupRepeatLabel( int x) {
// change the spelling based on the value of x
QString strVar2;
if ( x > 1 )
lblVar1->show();
else
lblVar1->hide();
switch ( currInterval ) {
case None:
break;
case Day:
if ( x > 1 )
strVar2 = tr( "days" );
else
strVar2 = tr( "day" );
break;
case Week:
if ( x > 1 )
strVar2 = tr( "weeks" );
else
strVar2 = tr( "week" );
break;
case Month:
if ( x > 1 )
strVar2 = tr( "months" );
else
strVar2 = tr( "month" );
break;
case Year:
if ( x > 1 )
strVar2 = tr( "years" );
else
strVar2 = tr( "year" );
break;
}
if ( !strVar2.isNull() )
lblVar2->setText( strVar2 );
}
void ORecurranceWidget::slotWeekLabel() {
QString str;
QListIterator<QToolButton> it( listExtra );
unsigned int i;
unsigned int keepMe;
bool bNeedCarriage = FALSE;
// don't do something we'll regret!!!
if ( currInterval != Week )
return;
if ( startWeekOnMonday )
keepMe = start.dayOfWeek() - 1;
else
keepMe = start.dayOfWeek() % 7;
QStringList list;
for ( i = 0; *it; ++it, i++ ) {
// a crazy check, if you are repeating weekly, the current day
// must be selected!!!
if ( i == keepMe && !( (*it)->isOn() ) )
(*it)->setOn( TRUE );
if ( (*it)->isOn() ) {
if ( startWeekOnMonday )
list.append( dayLabel[i] );
else {
if ( i == 0 )
list.append( dayLabel[6] );
else
list.append( dayLabel[i - 1] );
}
}
}
QStringList::Iterator itStr;
for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
if ( i == 3 )
bNeedCarriage = TRUE;
else
bNeedCarriage = FALSE;
if ( str.isNull() )
str = *itStr;
else if ( i == list.count() - 1 ) {
if ( i < 2 )
str += tr(" and ") + *itStr;
else {
if ( bNeedCarriage )
str += tr( ",\nand " ) + *itStr;
else
str += tr( ", and " ) + *itStr;
}
} else {
if ( bNeedCarriage )
str += ",\n" + *itStr;
else
str += ", " + *itStr;
}
}
str = str.prepend( "on " );
lblWeekVar->setText( str );
}
void ORecurranceWidget::slotMonthLabel(int type) {
QString str;
if ( currInterval != Month || type > 1 )
return;
if ( type == 1 )
str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
else
str = strMonthDayTemplate.arg( numberPlacing(week(start)))
.arg( dayLabel[start.dayOfWeek() - 1] );
lblRepeat->setText( str );
}
void ORecurranceWidget::slotChangeStartOfWeek( bool onMonday ) {
startWeekOnMonday = onMonday;
// we need to make this unintrusive as possible...
int saveSpin = spinFreq->value();
char days = 0;
int day;
QListIterator<QToolButton> itExtra( listExtra );
for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
if ( (*itExtra)->isOn() ) {
if ( !startWeekOnMonday )
days |= day;
else {
if ( day == 1 )
days |= ORecur::SUN;
else
days |= day >> 1;
}
}
}
setupWeekly();
spinFreq->setValue( saveSpin );
int buttons;
for ( day = 0x01, buttons = 0; buttons < 7;
day = day << 1, buttons++ ) {
if ( days & day ) {
if ( startWeekOnMonday )
fraExtra->setButton( buttons );
else {
if ( buttons == 7 )
fraExtra->setButton( 0 );
else
fraExtra->setButton( buttons + 1 );
}
}
}
slotWeekLabel();
}
void ORecurranceWidget::setupNone() {
lblRepeat->setText( tr("No Repeat") );
lblVar1->hide();
lblVar2->hide();
hideExtras();
cmdEnd->hide();
lblFreq->hide();
lblEvery->hide();
lblFreq->hide();
spinFreq->hide();
lblEnd->hide();
lblWeekVar->hide();
}
void ORecurranceWidget::setupDaily() {
hideExtras();
lblWeekVar->hide();
spinFreq->setValue( 1 );
lblFreq->setText( tr("day(s)") );
lblVar2->show();
showRepeatStuff();
lblRepeat->setText( strDayTemplate );
setupRepeatLabel( 1 );
}
void ORecurranceWidget::setupWeekly() {
// reshow the buttons...
fraExtra->setTitle( tr("Repeat On") );
fraExtra->setExclusive( FALSE );
fraExtra->show();
if ( startWeekOnMonday ) {
cmdExtra1->setText( tr("Mon") );
cmdExtra2->setText( tr("Tue") );
cmdExtra3->setText( tr("Wed") );
cmdExtra4->setText( tr("Thu") );
cmdExtra5->setText( tr("Fri") );
cmdExtra6->setText( tr("Sat") );
cmdExtra7->setText( tr("Sun") );
} else {
cmdExtra1->setText( tr("Sun") );
cmdExtra2->setText( tr("Mon") );
cmdExtra3->setText( tr("Tue") );
cmdExtra4->setText( tr("Wed") );
cmdExtra5->setText( tr("Thu") );
cmdExtra6->setText( tr("Fri") );
cmdExtra7->setText( tr("Sat") );
}
// I hope clustering these improve performance....
cmdExtra1->setOn( FALSE );
cmdExtra2->setOn( FALSE );
cmdExtra3->setOn( FALSE );
cmdExtra4->setOn( FALSE );
cmdExtra5->setOn( FALSE );
cmdExtra6->setOn( FALSE );
cmdExtra7->setOn( FALSE );
cmdExtra1->show();
cmdExtra2->show();
cmdExtra3->show();
cmdExtra4->show();
cmdExtra5->show();
cmdExtra6->show();
cmdExtra7->show();
lblWeekVar->show();
spinFreq->setValue( 1 );
// might as well set the day too...
if ( startWeekOnMonday ) {
fraExtra->setButton( start.dayOfWeek() - 1 );
} else {
fraExtra->setButton( start.dayOfWeek() % 7 );
}
lblFreq->setText( tr("week(s)") );
lblVar2->show();
showRepeatStuff();
setupRepeatLabel( 1 );
}
void ORecurranceWidget::setupMonthly() {
hideExtras();
lblWeekVar->hide();
fraExtra->setTitle( tr("Repeat By") );
fraExtra->setExclusive( TRUE );
fraExtra->show();
cmdExtra1->setText( tr("Day") );
cmdExtra1->show();
cmdExtra2->setText( tr("Date") );
cmdExtra2->show();
spinFreq->setValue( 1 );
lblFreq->setText( tr("month(s)") );
lblVar2->show();
showRepeatStuff();
setupRepeatLabel( 1 );
}
void ORecurranceWidget::setupYearly() {
hideExtras();
lblWeekVar->hide();
spinFreq->setValue( 1 );
lblFreq->setText( tr("year(s)") );
lblFreq->show();
lblFreq->show();
showRepeatStuff();
lblVar2->show();
QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
lblRepeat->setText( strEvery );
setupRepeatLabel( 1 );
}
void ORecurranceWidget::init() {
QPopupMenu *m1 = new QPopupMenu( this );
repeatPicker = new DateBookMonth( m1, 0, TRUE );
m1->insertItem( repeatPicker );
cmdEnd->setPopup( m1 );
cmdEnd->setPopupDelay( 0 );
QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
this, SLOT(endDateChanged(int, int, int)) );
QObject::connect( qApp, SIGNAL(weekChanged(bool)),
this, SLOT(slotChangeStartOfWeek(bool)) );
listRTypeButtons.setAutoDelete( TRUE );
listRTypeButtons.append( cmdNone );
listRTypeButtons.append( cmdDay );
listRTypeButtons.append( cmdWeek );
listRTypeButtons.append( cmdMonth );
listRTypeButtons.append( cmdYear );
listExtra.setAutoDelete( TRUE );
listExtra.append( cmdExtra1 );
listExtra.append( cmdExtra2 );
listExtra.append( cmdExtra3 );
listExtra.append( cmdExtra4 );
listExtra.append( cmdExtra5 );
listExtra.append( cmdExtra6 );
listExtra.append( cmdExtra7 );
}
void ORecurranceWidget::hideExtras() {
// hide the extra buttons...
fraExtra->hide();
chkNoEnd->hide();
QListIterator<QToolButton> it( listExtra );
for ( ; *it; ++it ) {
(*it)->hide();
(*it)->setOn( FALSE );
}
}
void ORecurranceWidget::showRepeatStuff() {
cmdEnd->show();
chkNoEnd->show();
lblFreq->show();
lblEvery->show();
lblFreq->show();
spinFreq->show();
lblEnd->show();
lblRepeat->setText( tr("Every") );
}
static int week( const QDate &start )
{
// figure out the week...
int stop = start.day(),
sentinel = start.dayOfWeek(),
dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
week = 1,
i;
for ( i = 1; i < stop; i++ ) {
if ( dayOfWeek++ == sentinel )
week++;
if ( dayOfWeek > 7 )
dayOfWeek = 0;
}
return week;
}
static QString numberPlacing( int x )
{
// I hope this works in other languages besides english...
QString str = QString::number( x );
switch ( x % 10 ) {
case 1:
str += QWidget::tr( "st" );
break;
case 2:
str += QWidget::tr( "nd" );
break;
case 3:
str += QWidget::tr( "rd" );
break;
default:
str += QWidget::tr( "th" );
diff --git a/libopie/pim/ocontactaccessbackend_vcard.cpp b/libopie/pim/ocontactaccessbackend_vcard.cpp
index 622d40a..e537269 100644
--- a/libopie/pim/ocontactaccessbackend_vcard.cpp
+++ b/libopie/pim/ocontactaccessbackend_vcard.cpp
@@ -1,461 +1,470 @@
/*
* VCard Backend for the OPIE-Contact Database.
*
* Copyright (C) 2000 Trolltech AS. All rights reserved.
* Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* =====================================================================
* ToDo:
*
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.8 2003/02/21 16:52:49 zecke
+ * -Remove old Todo classes they're deprecated and today I already using the
+ * new API
+ * -Guard against self assignment in OTodo
+ * -Add test apps for OPIM
+ * -Opiefied Event classes
+ * -Added TimeZone handling and pinning of TimeZones to OEvent
+ * -Adjust ORecur and the widget to better timezone behaviour
+ *
* Revision 1.7 2003/02/16 22:25:46 zecke
* 0000276 Fix for that bug.. or better temp workaround
* A Preferred Number is HOME|VOICE
* A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test
* triggers both
* and the cell phone number overrides the other entries..
*
* as a temp I check that it's not equal to HOME|VOICE|CELL before setting the
* number
*
* The right and final fix would be to reorder the if statement to make it
* if else based and the less common thing put to the bottom
*
* OTodoAccessVcal fix the date for beaming
*
* Revision 1.6 2003/01/13 15:49:31 eilers
* Fixing crash when businesscard.vcf is missing..
*
* Revision 1.5 2002/12/07 13:26:22 eilers
* Fixing bug in storing anniversary..
*
* Revision 1.4 2002/11/13 14:14:51 eilers
* Added sorted for Contacts..
*
* Revision 1.3 2002/11/11 16:41:09 kergoth
* no default arguments in implementation
*
* Revision 1.2 2002/11/10 15:41:53 eilers
* Bugfixes..
*
* Revision 1.1 2002/11/09 14:34:52 eilers
* Added VCard Backend.
*
*/
#include "ocontactaccessbackend_vcard.h"
#include "../../library/backend/vobject_p.h"
#include "../../library/backend/qfiledirect_p.h"
#include <qpe/timeconversion.h>
#include <qfile.h>
OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ):
m_dirty( false ),
m_file( filename )
{
load();
}
bool OContactAccessBackend_VCard::load ()
{
m_map.clear();
m_dirty = false;
VObject* obj = 0l;
- if ( QFile( m_file ).exists() ){
+ if ( QFile::exists(m_file) ){
obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
if ( !obj )
return false;
}else{
qWarning("File \"%s\" not found !", m_file.latin1() );
return false;
}
while ( obj ) {
OContact con = parseVObject( obj );
/*
* if uid is 0 assign a new one
* this at least happens on
* Nokia6210
*/
if ( con.uid() == 0 ){
con.setUid( 1 );
qWarning("assigned new uid %d",con.uid() );
}
m_map.insert( con.uid(), con );
VObject *t = obj;
obj = nextVObjectInList(obj);
cleanVObject( t );
}
return true;
}
bool OContactAccessBackend_VCard::reload()
{
return load();
}
bool OContactAccessBackend_VCard::save()
{
if (!m_dirty )
return true;
QFileDirect file( m_file );
if (!file.open(IO_WriteOnly ) )
return false;
VObject *obj;
obj = newVObject( VCCalProp );
addPropValue( obj, VCVersionProp, "1.0" );
VObject *vo;
for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
vo = createVObject( *it );
writeVObject( file.directHandle() , vo );
cleanVObject( vo );
}
cleanStrTbl();
m_dirty = false;
return true;
}
void OContactAccessBackend_VCard::clear ()
{
m_map.clear();
m_dirty = true; // ??? sure ? (se)
}
bool OContactAccessBackend_VCard::add ( const OContact& newcontact )
{
m_map.insert( newcontact.uid(), newcontact );
m_dirty = true;
return true;
}
bool OContactAccessBackend_VCard::remove ( int uid )
{
m_map.remove( uid );
m_dirty = true;
return true;
}
bool OContactAccessBackend_VCard::replace ( const OContact &contact )
{
m_map.replace( contact.uid(), contact );
m_dirty = true;
return true;
}
OContact OContactAccessBackend_VCard::find ( int uid ) const
{
return m_map[uid];
}
QArray<int> OContactAccessBackend_VCard::allRecords() const
{
QArray<int> ar( m_map.count() );
QMap<int, OContact>::ConstIterator it;
int i = 0;
for ( it = m_map.begin(); it != m_map.end(); ++it ) {
ar[i] = it.key();
i++;
}
return ar;
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int )
{
QArray<int> ar(0);
return ar;
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
{
QArray<int> ar(0);
return ar;
}
const uint OContactAccessBackend_VCard::querySettings()
{
return 0; // No search possible
}
bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const
{
return false; // No search possible, therefore all settings invalid ;)
}
bool OContactAccessBackend_VCard::wasChangedExternally()
{
return false; // Don't expect concurrent access
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int )
{
QArray<int> ar(0);
return ar;
}
// *** Private stuff ***
OContact OContactAccessBackend_VCard::parseVObject( VObject *obj )
{
OContact c;
VObjectIterator it;
initPropIterator( &it, obj );
while( moreIteration( &it ) ) {
VObject *o = nextVObject( &it );
QCString name = vObjectName( o );
QCString value = vObjectStringZValue( o );
if ( name == VCNameProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
QString value = vObjectStringZValue( o );
if ( name == VCNamePrefixesProp )
c.setTitle( value );
else if ( name == VCNameSuffixesProp )
c.setSuffix( value );
else if ( name == VCFamilyNameProp )
c.setLastName( value );
else if ( name == VCGivenNameProp )
c.setFirstName( value );
else if ( name == VCAdditionalNamesProp )
c.setMiddleName( value );
}
}
else if ( name == VCAdrProp ) {
bool work = TRUE; // default address is work address
QString street;
QString city;
QString region;
QString postal;
QString country;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
if ( name == VCHomeProp )
work = FALSE;
else if ( name == VCWorkProp )
work = TRUE;
else if ( name == VCStreetAddressProp )
street = value;
else if ( name == VCCityProp )
city = value;
else if ( name == VCRegionProp )
region = value;
else if ( name == VCPostalCodeProp )
postal = value;
else if ( name == VCCountryNameProp )
country = value;
}
if ( work ) {
c.setBusinessStreet( street );
c.setBusinessCity( city );
c.setBusinessCountry( country );
c.setBusinessZip( postal );
c.setBusinessState( region );
} else {
c.setHomeStreet( street );
c.setHomeCity( city );
c.setHomeCountry( country );
c.setHomeZip( postal );
c.setHomeState( region );
}
}
else if ( name == VCTelephoneProp ) {
enum {
HOME = 0x01,
WORK = 0x02,
VOICE = 0x04,
CELL = 0x08,
FAX = 0x10,
PAGER = 0x20,
UNKNOWN = 0x80
};
int type = 0;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name == VCHomeProp )
type |= HOME;
else if ( name == VCWorkProp )
type |= WORK;
else if ( name == VCVoiceProp )
type |= VOICE;
else if ( name == VCCellularProp )
type |= CELL;
else if ( name == VCFaxProp )
type |= FAX;
else if ( name == VCPagerProp )
type |= PAGER;
else if ( name == VCPreferredProp )
;
else
type |= UNKNOWN;
}
if ( (type & UNKNOWN) != UNKNOWN ) {
if ( ( type & (HOME|WORK) ) == 0 ) // default
type |= HOME;
if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
type |= VOICE;
qWarning("value %s %d", value.data(), type );
if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) )
c.setHomePhone( value );
if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
c.setHomeFax( value );
if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
c.setHomeMobile( value );
if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) )
c.setBusinessPhone( value );
if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
c.setBusinessFax( value );
if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
c.setBusinessMobile( value );
if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
c.setBusinessPager( value );
}
}
else if ( name == VCEmailAddressProp ) {
QString email = vObjectStringZValue( o );
bool valid = TRUE;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name != VCInternetProp && name != VCHomeProp &&
name != VCWorkProp &&
name != VCPreferredProp )
// ### preffered should map to default email
valid = FALSE;
}
if ( valid ) {
c.insertEmail( email );
}
}
else if ( name == VCURLProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name == VCHomeProp )
c.setHomeWebpage( value );
else if ( name == VCWorkProp )
c.setBusinessWebpage( value );
}
}
else if ( name == VCOrgProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
if ( name == VCOrgNameProp )
c.setCompany( value );
else if ( name == VCOrgUnitProp )
c.setDepartment( value );
else if ( name == VCOrgUnit2Prop )
c.setOffice( value );
}
}
else if ( name == VCTitleProp ) {
c.setJobTitle( value );
}
else if ( name == "X-Qtopia-Profession" ) {
c.setProfession( value );
}
else if ( name == "X-Qtopia-Manager" ) {
c.setManager( value );
}
else if ( name == "X-Qtopia-Assistant" ) {
c.setAssistant( value );
}
else if ( name == "X-Qtopia-Spouse" ) {
c.setSpouse( value );
}
else if ( name == "X-Qtopia-Gender" ) {
c.setGender( value );
}
else if ( name == "X-Qtopia-Anniversary" ) {
c.setAnniversary( convVCardDateToDate( value ) );
}
else if ( name == "X-Qtopia-Nickname" ) {
c.setNickname( value );
}
else if ( name == "X-Qtopia-Children" ) {
c.setChildren( value );
}
else if ( name == VCBirthDateProp ) {
// Reading Birthdate regarding RFC 2425 (5.8.4)
c.setBirthday( convVCardDateToDate( value ) );
}
#if 0
else {
printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
printf(" subprop: %s = %s\n", name.data(), value.latin1() );
}
}
#endif
}
c.setFileAs();
return c;
}
VObject* OContactAccessBackend_VCard::createVObject( const OContact &c )
{
VObject *vcard = newVObject( VCCardProp );
safeAddPropValue( vcard, VCVersionProp, "2.1" );
safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
// full name
safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
// name properties
VObject *name = safeAddProp( vcard, VCNameProp );
safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
safeAddPropValue( name, VCGivenNameProp, c.firstName() );
safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp
new file mode 100644
index 0000000..71b9441
--- a/dev/null
+++ b/libopie/pim/oevent.cpp
@@ -0,0 +1,427 @@
+#include <qshared.h>
+
+#include <qpe/palmtopuidgen.h>
+#include <qpe/categories.h>
+
+#include "orecur.h"
+#include "opimresolver.h"
+#include "opimnotifymanager.h"
+
+#include "oevent.h"
+
+namespace OCalendarHelper {
+ static int week( const QDate& date) {
+ // Calculates the week this date is in within that
+ // month. Equals the "row" is is in in the month view
+ int week = 1;
+ QDate tmp( date.year(), date.month(), 1 );
+ if ( date.dayOfWeek() < tmp.dayOfWeek() )
+ ++week;
+
+ week += ( date.day() - 1 ) / 7;
+
+ return week;
+ }
+ static int occurence( const QDate& date) {
+ // calculates the number of occurrances of this day of the
+ // week till the given date (e.g 3rd Wednesday of the month)
+ return ( date.day() - 1 ) / 7 + 1;
+ }
+ static int dayOfWeek( char day ) {
+ int dayOfWeek = 1;
+ char i = ORecur::MON;
+ while ( !( i & day ) && i <= ORecur::SUN ) {
+ i <<= 1;
+ ++dayOfWeek;
+ }
+ return dayOfWeek;
+ }
+ static int monthDiff( const QDate& first, const QDate& second ) {
+ return ( second.year() - first.year() ) * 12 +
+ second.month() - first.month();
+ }
+}
+
+struct OEvent::Data : public QShared {
+ Data() : QShared() {
+ recur = 0;
+ manager = 0;
+ isAllDay = false;
+ }
+ ~Data() {
+ delete manager;
+ delete recur;
+ }
+ QString description;
+ QString location;
+ OPimNotifyManager* manager;
+ ORecur* recur;
+ QString note;
+ QDateTime created;
+ QDateTime start;
+ QDateTime end;
+ bool isAllDay : 1;
+ QString timezone;
+};
+
+OEvent::OEvent( int uid )
+ : OPimRecord( uid ) {
+ data = new Data;
+}
+OEvent::OEvent( const OEvent& ev)
+ : OPimRecord( ev ), data( ev.data )
+{
+ data->ref();
+}
+OEvent::~OEvent() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+OEvent& OEvent::operator=( const OEvent& ev) {
+ if ( *this == ev ) return *this;
+
+ OPimRecord::operator=( ev );
+ ev.data->ref();
+ deref();
+ data = ev.data;
+
+
+ return *this;
+}
+QString OEvent::description()const {
+ return data->description;
+}
+void OEvent::setDescription( const QString& description ) {
+ changeOrModify();
+ data->description = description;
+}
+void OEvent::setLocation( const QString& loc ) {
+ changeOrModify();
+ data->location = loc;
+}
+QString OEvent::location()const {
+ return data->location;
+}
+OPimNotifyManager &OEvent::notifiers() {
+ // I hope we can skip the changeOrModify here
+ // the notifier should take care of it
+ // and OPimNotify is shared too
+ if (!data->manager )
+ data->manager = new OPimNotifyManager;
+
+ return *data->manager;
+}
+bool OEvent::hasNotifiers()const {
+ return ( data->manager);
+}
+ORecur OEvent::recurrence()const {
+ if (!data->recur)
+ data->recur = new ORecur;
+
+ return *data->recur;
+}
+void OEvent::setRecurrence( const ORecur& rec) {
+ changeOrModify();
+ if (data->recur )
+ (*data->recur) = rec;
+ else
+ data->recur = new ORecur( rec );
+}
+bool OEvent::hasRecurrence()const {
+ return data->recur;
+}
+QString OEvent::note()const {
+ return data->note;
+}
+void OEvent::setNote( const QString& note ) {
+ changeOrModify();
+ data->note = note;
+}
+QDateTime OEvent::createdDateTime()const {
+ return data->created;
+}
+void OEvent::setCreatedDateTime( const QDateTime& time ) {
+ changeOrModify();
+ data->created = time;
+}
+QDateTime OEvent::startDateTime()const {
+ if ( data->isAllDay )
+ return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
+ return data->start;
+}
+QDateTime OEvent::startDateTimeInZone()const {
+ /* if no timezone, or all day event or if the current and this timeZone match... */
+ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
+
+ OTimeZone zone(data->timezone );
+ return zone.toDateTime( data->start, OTimeZone::current() );
+}
+void OEvent::setStartDateTime( const QDateTime& dt ) {
+ changeOrModify();
+ data->start = dt;
+}
+QDateTime OEvent::endDateTime()const {
+ /*
+ * if all Day event the end time needs
+ * to be on the same day as the start
+ */
+ if ( data->isAllDay )
+ return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
+ return data->end;
+}
+QDateTime OEvent::endDateTimeInZone()const {
+ /* if no timezone, or all day event or if the current and this timeZone match... */
+ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
+
+ OTimeZone zone(data->timezone );
+ return zone.toDateTime( data->end, OTimeZone::current() );
+}
+void OEvent::setEndDateTime( const QDateTime& dt ) {
+ changeOrModify();
+ data->end = dt;
+}
+bool OEvent::isMultipleDay()const {
+ return data->end.date().day() - data->start.date().day();
+}
+bool OEvent::isAllDay()const {
+ return data->isAllDay;
+}
+void OEvent::setTimeZone( const QString& tz ) {
+ changeOrModify();
+ data->timezone = tz;
+}
+QString OEvent::timeZone()const {
+ return data->timezone;
+}
+bool OEvent::match( const QRegExp& )const {
+ // FIXME
+ return false;
+}
+QString OEvent::toRichText()const {
+ // FIXME
+ return "OEvent test";
+}
+QString OEvent::toShortText()const {
+ return "OEvent shotText";
+}
+QString OEvent::type()const {
+ return QString::fromLatin1("OEvent");
+}
+QString OEvent::recordField( int /*id */ )const {
+ return QString::null;
+}
+int OEvent::rtti() {
+ return OPimResolver::DateBook;
+}
+bool OEvent::loadFromStream( QDataStream& ) {
+ return true;
+}
+bool OEvent::saveToStream( QDataStream& )const {
+ return true;
+}
+void OEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->description = data->description;
+ d2->location = data->location;
+ d2->manager = data->manager;
+ d2->recur = data->recur;
+ d2->note = data->note;
+ d2->created = data->created;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->isAllDay = data->isAllDay;
+ d2->timezone = data->timezone;
+
+ data = d2;
+ }
+}
+void OEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+// FIXME
+QMap<int, QString> OEvent::toMap()const {
+ return QMap<int, QString>();
+}
+QMap<QString, QString> OEvent::toExtraMap()const {
+ return QMap<QString, QString>();
+}
+
+
+struct OEffectiveEvent::Data : public QShared {
+ Data() : QShared() {
+ }
+ OEvent event;
+ QDate date;
+ QTime start, end;
+ QDate startDate, endDate;
+ bool dates : 1;
+};
+
+OEffectiveEvent::OEffectiveEvent() {
+ data = new Data;
+ data->date = QDate::currentDate();
+ data->start = data->end = QTime::currentTime();
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
+ Position pos ) {
+ data = new Data;
+ data->event = ev;
+ data->date = startDate;
+ if ( pos & Start )
+ data->start = ev.startDateTime().time();
+ else
+ data->start = QTime( 0, 0, 0 );
+
+ if ( pos & End )
+ data->end = ev.endDateTime().time();
+ else
+ data->end = QTime( 23, 59, 59 );
+
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
+ data = ev.data;
+ data->ref();
+}
+OEffectiveEvent::~OEffectiveEvent() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
+ if ( *this == ev ) return *this;
+
+ ev.data->ref();
+ deref();
+ data = ev.data;
+
+ return *this;
+}
+
+void OEffectiveEvent::setStartTime( const QTime& ti) {
+ changeOrModify();
+ data->start = ti;
+}
+void OEffectiveEvent::setEndTime( const QTime& en) {
+ changeOrModify();
+ data->end = en;
+}
+void OEffectiveEvent::setEvent( const OEvent& ev) {
+ changeOrModify();
+ data->event = ev;
+}
+void OEffectiveEvent::setDate( const QDate& da) {
+ changeOrModify();
+ data->date = da;
+}
+void OEffectiveEvent::setEffectiveDates( const QDate& from,
+ const QDate& to ) {
+ if (!from.isValid() ) {
+ data->dates = false;
+ return;
+ }
+
+ data->startDate = from;
+ data->endDate = to;
+}
+QString OEffectiveEvent::description()const {
+ return data->event.description();
+}
+QString OEffectiveEvent::location()const {
+ return data->event.location();
+}
+QString OEffectiveEvent::note()const {
+ return data->event.note();
+}
+OEvent OEffectiveEvent::event()const {
+ return data->event;
+}
+QTime OEffectiveEvent::startTime()const {
+ return data->start;
+}
+QTime OEffectiveEvent::endTime()const {
+ return data->end;
+}
+QDate OEffectiveEvent::date()const {
+ return data->date;
+}
+int OEffectiveEvent::length()const {
+ return (data->end.hour() * 60 - data->start.hour() * 60)
+ + QABS(data->start.minute() - data->end.minute() );
+}
+int OEffectiveEvent::size()const {
+ return ( data->end.hour() - data->start.hour() ) * 3600
+ + (data->end.minute() - data->start.minute() * 60
+ + data->end.second() - data->start.second() );
+}
+QDate OEffectiveEvent::startDate()const {
+ if ( data->dates )
+ return data->startDate;
+ else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
+ return data->date;
+ else
+ return data->event.startDateTime().date();
+}
+QDate OEffectiveEvent::endDate()const {
+ if ( data->dates )
+ return data->endDate;
+ else if ( data->event.hasRecurrence() )
+ return data->date;
+ else
+ return data->event.endDateTime().date();
+}
+void OEffectiveEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+void OEffectiveEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->event = data->event;
+ d2->date = data->date;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->startDate = data->startDate;
+ d2->endDate = data->endDate;
+ d2->dates = data->dates;
+ data = d2;
+ }
+}
+bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{
+ if ( data->date < e.date() )
+ return TRUE;
+ if ( data->date == e.date() )
+ return ( startTime() < e.startTime() );
+ else
+ return FALSE;
+}
+bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{
+ return (data->date <= e.date() );
+}
+bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const {
+ return ( date() == e.date()
+ && startTime() == e.startTime()
+ && endTime()== e.endTime()
+ && event() == e.event() );
+}
+bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const {
+ return !(*this == e );
+}
+bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const {
+ return !(*this <= e );
+}
+bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const {
+ return !(*this < e);
+}
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h
new file mode 100644
index 0000000..4489be7
--- a/dev/null
+++ b/libopie/pim/oevent.h
@@ -0,0 +1,198 @@
+// CONTAINS GPLed code of TT
+
+#ifndef OPIE_PIM_EVENT_H
+#define OPIE_PIM_EVENT_H
+
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qvaluelist.h>
+
+#include <qpe/recordfields.h>
+#include <qpe/palmtopuidgen.h>
+
+#include "otimezone.h"
+#include "opimrecord.h"
+
+namespace OCalendarHelper {
+ /** calculate the week number of the date */
+ static int week( const QDate& );
+ /** calculate the occurence of week days since the start of the month */
+ static int ocurrence( const QDate& );
+
+ // returns the dayOfWeek for the *first* day it finds (ignores
+ // any further days!). Returns 1 (Monday) if there isn't any day found
+ static int dayOfWeek( char day );
+
+ /** returns the diff of month */
+ static int monthDiff( const QDate& first, const QDate& second );
+
+}
+
+class OPimNotifyManager;
+class ORecur;
+class OEvent : public OPimRecord {
+public:
+ typedef QValueList<OEvent> ValueList;
+ enum RecordFields {
+ Uid = Qtopia::UID_ID,
+ Category = Qtopia::CATEGORY_ID,
+ Description,
+ Location,
+ Alarm,
+ Reminder,
+ Recurrence,
+ Note,
+ Created,
+ StartDate,
+ EndDate,
+ AllDay,
+ TimeZone
+ };
+
+ OEvent(int uid = 0);
+ OEvent( const OEvent& );
+ ~OEvent();
+ OEvent &operator=( const OEvent& );
+
+ QString description()const;
+ void setDescription( const QString& description );
+
+ QString location()const;
+ void setLocation( const QString& loc );
+
+ bool hasNotifiers()const;
+ OPimNotifyManager &notifiers();
+
+ ORecur recurrence()const;
+ void setRecurrence( const ORecur& );
+ bool hasRecurrence()const;
+
+ QString note()const;
+ void setNote( const QString& note );
+
+
+ QDateTime createdDateTime()const;
+ void setCreatedDateTime( const QDateTime& dt);
+
+ /** set the date to dt. dt is the QDateTime in localtime */
+ void setStartDateTime( const QDateTime& );
+ /** returns the datetime in the local timeZone */
+ QDateTime startDateTime()const;
+
+ /** returns the start datetime in the current zone */
+ QDateTime startDateTimeInZone()const;
+
+ /** in current timezone */
+ void setEndDateTime( const QDateTime& );
+ /** in current timezone */
+ QDateTime endDateTime()const;
+ QDateTime endDateTimeInZone()const;
+
+ bool isMultipleDay()const;
+ bool isAllDay()const;
+ void setAllDay( bool isAllDay );
+
+ /* pin this event to a timezone! FIXME */
+ void setTimeZone( const QString& timeZone );
+ QString timeZone()const;
+
+
+ bool match( const QRegExp& )const;
+
+
+
+
+ /* needed reimp */
+ QString toRichText()const;
+ QString toShortText()const;
+ QString type()const;
+
+ QMap<int, QString> toMap()const;
+ QMap<QString, QString> toExtraMap()const;
+ QString recordField(int )const;
+
+ static int rtti();
+
+ bool loadFromStream( QDataStream& );
+ bool saveToStream( QDataStream& )const;
+
+/* bool operator==( const OEvent& );
+ bool operator!=( const OEvent& );
+ bool operator<( const OEvent& );
+ bool operator<=( const OEvent& );
+ bool operator>( const OEvent& );
+ bool operator>=(const OEvent& );
+*/
+private:
+ inline void changeOrModify();
+ void deref();
+ struct Data;
+ Data* data;
+ class Private;
+ Private* priv;
+
+};
+
+/**
+ * AN Event can span through multiple days. We split up a multiday eve
+ */
+
+class OEffectiveEvent {
+public:
+ QValueList<OEffectiveEvent> ValueList;
+ enum Position { MidWay, Start, End, StartEnd };
+ // If we calculate the effective event of a multi-day event
+ // we have to figure out whether we are at the first day,
+ // at the end, or anywhere else ("middle"). This is important
+ // for the start/end times (00:00/23:59)
+ // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi-
+ // day event
+ // Start: start time -> 23:59
+ // End: 00:00 -> end time
+ // Start | End == StartEnd: for single-day events (default)
+ // here we draw start time -> end time
+ OEffectiveEvent();
+ OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd );
+ OEffectiveEvent( const OEffectiveEvent& );
+ OEffectiveEvent &operator=(const OEffectiveEvent& );
+ ~OEffectiveEvent();
+
+ void setStartTime( const QTime& );
+ void setEndTime( const QTime& );
+ void setEvent( const OEvent& );
+ void setDate( const QDate& );
+
+ void setEffectiveDates( const QDate& from, const QDate& to );
+
+ QString description()const;
+ QString location()const;
+ QString note()const;
+ OEvent event()const;
+ QTime startTime()const;
+ QTime endTime()const;
+ QDate date()const;
+
+ /* return the length in hours */
+ int length()const;
+ int size()const;
+
+ QDate startDate()const;
+ QDate endDate()const;
+
+ bool operator<( const OEffectiveEvent &e ) const;
+ bool operator<=( const OEffectiveEvent &e ) const;
+ bool operator==( const OEffectiveEvent &e ) const;
+ bool operator!=( const OEffectiveEvent &e ) const;
+ bool operator>( const OEffectiveEvent &e ) const;
+ bool operator>= ( const OEffectiveEvent &e ) const;
+
+private:
+ void deref();
+ inline void changeOrModify();
+ class Private;
+ Private* priv;
+ struct Data;
+ Data* data;
+
+};
+#endif
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp
index daf3506..e6a4787 100644
--- a/libopie/pim/orecur.cpp
+++ b/libopie/pim/orecur.cpp
@@ -1,451 +1,446 @@
#include <qshared.h>
#include <qtopia/timeconversion.h>
#include "orecur.h"
struct ORecur::Data : public QShared {
Data() : QShared() {
type = ORecur::NoRepeat;
freq = -1;
days = 0;
pos = 0;
- create = -1;
+ create = QDateTime::currentDateTime();
hasEnd = FALSE;
- end = 0;
+ end = QDate::currentDate();
}
char days; // Q_UINT8 for 8 seven days;)
ORecur::RepeatType type;
int freq;
int pos;
bool hasEnd : 1;
- time_t end;
- time_t create;
+ QDate end;
+ QDateTime create;
int rep;
QString app;
ExceptionList list;
QDate start;
};
ORecur::ORecur() {
data = new Data;
}
ORecur::ORecur( const ORecur& rec)
: data( rec.data )
{
data->ref();
}
ORecur::~ORecur() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
void ORecur::deref() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
bool ORecur::operator==( const ORecur& )const {
return false;
}
ORecur &ORecur::operator=( const ORecur& re) {
+ if ( *this == re ) return *this;
+
re.data->ref();
deref();
data = re.data;
return *this;
}
bool ORecur::doesRecur()const {
return !( type() == NoRepeat );
}
/*
* we try to be smart here
*
*/
bool ORecur::doesRecur( const QDate& date ) {
/* the day before the recurrance */
QDate da = date.addDays(-1);
QDate recur;
if (!nextOcurrence( da, recur ) )
return false;
return (recur == date);
}
// FIXME unuglify!
// GPL from Datebookdb.cpp
// FIXME exception list!
bool ORecur::nextOcurrence( const QDate& from, QDate& next ) {
// easy checks, first are we too far in the future or too far in the past?
QDate tmpDate;
int freq = frequency();
int diff, diff2, a;
int iday, imonth, iyear;
int dayOfWeek = 0;
int firstOfWeek = 0;
int weekOfMonth;
if (hasEndDate() && endDate() < from)
return FALSE;
if (start() >= from) {
next = start();
return TRUE;
}
switch ( type() ) {
case Weekly:
/* weekly is just daily by 7 */
/* first convert the repeatPattern.Days() mask to the next
day of week valid after from */
dayOfWeek = from.dayOfWeek();
dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
/* this is done in case freq > 1 and from in week not
for this round */
// firstOfWeek = 0; this is already done at decl.
while(!((1 << firstOfWeek) & days() ))
firstOfWeek++;
/* there is at least one 'day', or there would be no event */
while(!((1 << (dayOfWeek % 7)) & days() ))
dayOfWeek++;
dayOfWeek = dayOfWeek % 7; /* the actual day of week */
dayOfWeek -= start().dayOfWeek() -1;
firstOfWeek = firstOfWeek % 7; /* the actual first of week */
firstOfWeek -= start().dayOfWeek() -1;
// dayOfWeek may be negitive now
// day of week is number of days to add to start day
freq *= 7;
// FALL-THROUGH !!!!!
case Daily:
// the add is for the possible fall through from weekly */
if(start().addDays(dayOfWeek) > from) {
/* first week exception */
next = QDate(start().addDays(dayOfWeek) );
if ((next > endDate())
&& hasEndDate() )
return FALSE;
return TRUE;
}
/* if from is middle of a non-week */
diff = start().addDays(dayOfWeek).daysTo(from) % freq;
diff2 = start().addDays(firstOfWeek).daysTo(from) % freq;
if(diff != 0)
diff = freq - diff;
if(diff2 != 0)
diff2 = freq - diff2;
diff = QMIN(diff, diff2);
next = QDate(from.addDays(diff));
if ( (next > endDate())
&& hasEndDate() )
return FALSE;
return TRUE;
case MonthlyDay:
iday = from.day();
iyear = from.year();
imonth = from.month();
/* find equivelent day of month for this month */
dayOfWeek = start().dayOfWeek();
weekOfMonth = (start().day() - 1) / 7;
/* work out when the next valid month is */
a = from.year() - start().year();
a *= 12;
a = a + (imonth - start().month());
/* a is e.start()monthsFrom(from); */
if(a % freq) {
a = freq - (a % freq);
imonth = from.month() + a;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
}
/* imonth is now the first month after or on
from that matches the frequency given */
/* find for this month */
tmpDate = QDate( iyear, imonth, 1 );
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
while (iday > tmpDate.daysInMonth()) {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
tmpDate = QDate( iyear, imonth, 1 );
/* these loops could go for a while, check end case now */
if ((tmpDate > endDate()) && hasEndDate() )
return FALSE;
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
}
tmpDate = QDate(iyear, imonth, iday);
if (tmpDate >= from) {
next = tmpDate;
if ((next > endDate() ) && hasEndDate() )
return FALSE;
return TRUE;
}
/* need to find the next iteration */
do {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
tmpDate = QDate( iyear, imonth, 1 );
/* these loops could go for a while, check end case now */
if ((tmpDate > endDate()) && hasEndDate() )
return FALSE;
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
} while (iday > tmpDate.daysInMonth());
tmpDate = QDate(iyear, imonth, iday);
next = tmpDate;
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
case MonthlyDate:
iday = start().day();
iyear = from.year();
imonth = from.month();
a = from.year() - start().year();
a *= 12;
a = a + (imonth - start().month());
/* a is e.start()monthsFrom(from); */
if(a % freq) {
a = freq - (a % freq);
imonth = from.month() + a;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
}
/* imonth is now the first month after or on
from that matches the frequencey given */
/* this could go for a while, worse case, 4*12 iterations, probably */
while(!QDate::isValid(iyear, imonth, iday) ) {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
/* these loops could go for a while, check end case now */
if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
return FALSE;
}
if(QDate(iyear, imonth, iday) >= from) {
/* done */
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
}
/* ok, need to cycle */
imonth += freq;
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
while(!QDate::isValid(iyear, imonth, iday) ) {
imonth += freq;
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
return FALSE;
}
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
case Yearly:
iday = start().day();
imonth = start().month();
iyear = from.year(); // after all, we want to start in this year
diff = 1;
if(imonth == 2 && iday > 28) {
/* leap year, and it counts, calculate actual frequency */
if(freq % 4)
if (freq % 2)
freq = freq * 4;
else
freq = freq * 2;
/* else divides by 4 already, leave freq alone */
diff = 4;
}
a = from.year() - start().year();
if(a % freq) {
a = freq - (a % freq);
iyear = iyear + a;
}
/* under the assumption we won't hit one of the special not-leap years twice */
if(!QDate::isValid(iyear, imonth, iday)) {
/* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
iyear += freq;
}
if(QDate(iyear, imonth, iday) >= from) {
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
}
/* iyear == from.year(), need to advance again */
iyear += freq;
/* under the assumption we won't hit one of the special not-leap years twice */
if(!QDate::isValid(iyear, imonth, iday)) {
/* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
iyear += freq;
}
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
default:
return FALSE;
}
}
ORecur::RepeatType ORecur::type()const{
return data->type;
}
int ORecur::frequency()const {
return data->freq;
}
int ORecur::position()const {
return data->pos;
}
char ORecur::days() const{
return data->days;
}
bool ORecur::hasEndDate()const {
return data->hasEnd;
}
QDate ORecur::endDate()const {
- return TimeConversion::fromUTC( data->end ).date();
+ return data->end;
}
QDate ORecur::start()const{
return data->start;
}
-time_t ORecur::endDateUTC()const {
- return data->end;
-}
-time_t ORecur::createTime()const {
+QDateTime ORecur::createdDateTime()const {
return data->create;
}
int ORecur::repetition()const {
return data->rep;
}
QString ORecur::service()const {
return data->app;
}
ORecur::ExceptionList& ORecur::exceptions() {
return data->list;
}
void ORecur::setType( const RepeatType& z) {
checkOrModify();
data->type = z;
}
void ORecur::setFrequency( int freq ) {
checkOrModify();
data->freq = freq;
}
void ORecur::setPosition( int pos ) {
checkOrModify();
data->pos = pos;
}
void ORecur::setDays( char c ) {
checkOrModify();
data->days = c;
}
void ORecur::setEndDate( const QDate& dt) {
checkOrModify();
- data->end = TimeConversion::toUTC( dt );
-}
-void ORecur::setEndDateUTC( time_t t) {
- checkOrModify();
- data->end = t;
+ data->end = dt;
}
-void ORecur::setCreateTime( time_t t) {
+void ORecur::setCreatedDateTime( const QDateTime& t) {
checkOrModify();
data->create = t;
}
void ORecur::setHasEndDate( bool b) {
checkOrModify();
data->hasEnd = b;
}
void ORecur::setRepitition( int rep ) {
checkOrModify();
data->rep = rep;
}
void ORecur::setService( const QString& app ) {
checkOrModify();
data->app = app;
}
void ORecur::setStart( const QDate& dt ) {
checkOrModify();
data->start = dt;
}
void ORecur::checkOrModify() {
if ( data->count != 1 ) {
data->deref();
Data* d2 = new Data;
d2->days = data->days;
d2->type = data->type;
d2->freq = data->freq;
d2->pos = data->pos;
d2->hasEnd = data->hasEnd;
d2->end = data->end;
d2->create = data->create;
d2->rep = data->rep;
d2->app = data->app;
d2->list = data->list;
d2->start = data->start;
data = d2;
}
}
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h
index 8713d97..1e0014b 100644
--- a/libopie/pim/orecur.h
+++ b/libopie/pim/orecur.h
@@ -1,83 +1,87 @@
/*
* GPL from TT
*/
#ifndef OPIE_RECUR_H
#define OPIE_RECUR_H
#include <sys/types.h>
#include <qdatetime.h>
#include <qvaluelist.h>
class ORecur {
public:
typedef QValueList<QDate> ExceptionList;
enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
MonthlyDate, Yearly };
enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
FRI = 0x10, SAT = 0x20, SUN = 0x40 };
ORecur();
ORecur( const ORecur& );
~ORecur();
ORecur &operator=( const ORecur& );
bool operator==(const ORecur& )const;
bool doesRecur()const;
/* if it recurrs on that day */
bool doesRecur( const QDate& );
RepeatType type()const;
int frequency()const;
int position()const;
char days()const;
bool hasEndDate()const;
QDate start()const;
QDate endDate()const;
- time_t endDateUTC()const;
- time_t createTime()const;
+ QDateTime createdDateTime()const;
+ /**
+ * starting on monday=0, sunday=6
+ * for convience
+ */
+ bool repeatOnWeekDay( int day )const;
/**
* FromWhereToStart is not included!!!
*/
bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate );
+
/**
* The module this ORecur belongs to
*/
QString service()const;
/*
* reference to the exception list
*/
ExceptionList &exceptions();
/**
* the current repetition
*/
int repetition()const;
void setType( const RepeatType& );
void setFrequency( int freq );
void setPosition( int pos );
void setDays( char c);
void setEndDate( const QDate& dt );
void setStart( const QDate& dt );
- void setEndDateUTC( time_t );
- void setCreateTime( time_t );
+ void setCreatedDateTime( const QDateTime& );
void setHasEndDate( bool b );
void setRepitition(int );
void setService( const QString& ser );
private:
void deref();
inline void checkOrModify();
class Data;
Data* data;
class ORecurPrivate;
ORecurPrivate *d;
};
#endif
diff --git a/libopie/pim/otimezone.cpp b/libopie/pim/otimezone.cpp
new file mode 100644
index 0000000..b2bd3aa
--- a/dev/null
+++ b/libopie/pim/otimezone.cpp
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#include "otimezone.h"
+
+namespace {
+
+ QDateTime utcTime( time_t t) {
+ tm* broken = ::gmtime( &t );
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+ return ret;
+ }
+ QDateTime utcTime( time_t t, const QString& zone) {
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", zone.latin1(), true );
+ ::tzset();
+
+ tm* broken = ::localtime( &t );
+ ::setenv( "TZ", org, true );
+
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+
+ return ret;
+ }
+ time_t to_Time_t( const QDateTime& utc, const QString& str ) {
+ QDate d = utc.date();
+ QTime t = utc.time();
+
+ tm broken;
+ broken.tm_year = d.year() - 1900;
+ broken.tm_mon = d.month() - 1;
+ broken.tm_mday = d.day();
+ broken.tm_hour = t.hour();
+ broken.tm_min = t.minute();
+ broken.tm_sec = t.second();
+
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", str.latin1(), true );
+ ::tzset();
+
+ time_t ti = ::mktime( &broken );
+ ::setenv( "TZ", org, true );
+
+ return ti;
+ }
+}
+OTimeZone::OTimeZone( const ZoneName& zone )
+ : m_name(zone) {
+}
+OTimeZone::~OTimeZone() {
+}
+
+bool OTimeZone::isValid()const {
+ return !m_name.isEmpty();
+}
+
+/*
+ * we will get the current timezone
+ * and ask it to convert to the timezone date
+ */
+QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) {
+ return OTimeZone::current().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) {
+ return OTimeZone::utc().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::fromUTCDateTime( time_t t) {
+ return utcTime( t );
+}
+QDateTime OTimeZone::toDateTime( time_t t) {
+ return utcTime( t, m_name );
+}
+/*
+ * convert dt to utc using zone.m_name
+ * convert utc -> timeZoneDT using this->m_name
+ */
+QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) {
+ time_t utc = to_Time_t( dt, zone.m_name );
+ qWarning("%d %s", utc, zone.m_name.latin1() );
+ return utcTime( utc, m_name );
+}
+time_t OTimeZone::fromDateTime( const QDateTime& time ) {
+ return to_Time_t( time, m_name );
+}
+time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) {
+ return to_Time_t( time, "UTC" );
+}
+OTimeZone OTimeZone::current() {
+ QCString str = ::getenv("TZ");
+ OTimeZone zone( str );
+ return zone;
+}
+OTimeZone OTimeZone::utc() {
+ return OTimeZone("UTC");
+}
+QString OTimeZone::timeZone()const {
+ return m_name;
+}
diff --git a/libopie/pim/otimezone.h b/libopie/pim/otimezone.h
new file mode 100644
index 0000000..bb08349
--- a/dev/null
+++ b/libopie/pim/otimezone.h
@@ -0,0 +1,71 @@
+#ifndef OPIE_TIME_ZONE_H
+#define OPIE_TIME_ZONE_H
+
+#include <time.h>
+#include <qdatetime.h>
+
+/**
+ * A very primitive class to convert time
+ * from one timezone to another
+ * and to localtime
+ * and time_t
+ */
+class OTimeZone {
+ public:
+ typedef QString ZoneName;
+ OTimeZone( const ZoneName& = ZoneName::null );
+ virtual ~OTimeZone(); // just in case.
+
+ bool isValid()const;
+
+ /**
+ * converts the QDateTime to a DateTime
+ * in the local timezone
+ * if QDateTime is 25th Jan and takes place in Europe/Berlin at 12h
+ * and the current timezone is Europe/London the returned
+ * time will be 11h.
+ */
+ QDateTime toLocalDateTime( const QDateTime& dt );
+
+ /**
+ * converts the QDateTime to UTC time
+ */
+ QDateTime toUTCDateTime( const QDateTime& dt );
+
+ /**
+ * reads the time_t into a QDateTime using UTC as timezone!
+ */
+ QDateTime fromUTCDateTime( time_t );
+
+ /**
+ * converts the time_t to the time in the timezone
+ */
+ QDateTime toDateTime( time_t );
+
+ /**
+ * converts the QDateTime from one timezone to this timeZone
+ */
+ QDateTime toDateTime( const QDateTime&, const OTimeZone& timeZone );
+
+ /**
+ * converts the date time into a time_t. It takes the timezone into account
+ */
+ time_t fromDateTime( const QDateTime& );
+
+ /**
+ * converts the datetime with timezone UTC
+ */
+ time_t fromUTCDateTime( const QDateTime& );
+
+ static OTimeZone current();
+ static OTimeZone utc();
+
+ QString timeZone()const;
+ private:
+ ZoneName m_name;
+ class Private;
+ Private* d;
+};
+
+
+#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
index b4d4aa9..049359e 100644
--- a/libopie/pim/otodo.cpp
+++ b/libopie/pim/otodo.cpp
@@ -1,422 +1,424 @@
#include <qobject.h>
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/stringutil.h>
#include <qpe/palmtoprecord.h>
#include <qpe/stringutil.h>
#include <qpe/categories.h>
#include <qpe/categoryselect.h>
#include "opimstate.h"
#include "orecur.h"
#include "opimmaintainer.h"
#include "opimnotifymanager.h"
#include "opimresolver.h"
#include "otodo.h"
struct OTodo::OTodoData : public QShared {
OTodoData() : QShared() {
};
QDate date;
bool isCompleted:1;
bool hasDate:1;
int priority;
QString desc;
QString sum;
QMap<QString, QString> extra;
ushort prog;
OPimState state;
ORecur recur;
OPimMaintainer maintainer;
QDate start;
QDate completed;
OPimNotifyManager notifiers;
};
OTodo::OTodo(const OTodo &event )
: OPimRecord( event ), data( event.data )
{
data->ref();
// qWarning("ref up");
}
OTodo::~OTodo() {
// qWarning("~OTodo " );
if ( data->deref() ) {
// qWarning("OTodo::dereffing");
delete data;
data = 0l;
}
}
OTodo::OTodo(bool completed, int priority,
const QArray<int> &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData " + summary);
setCategories( category );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
}
OTodo::OTodo(bool completed, int priority,
const QStringList &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData" + summary);
setCategories( idsFromString( category.join(";") ) );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
}
bool OTodo::match( const QRegExp &regExp )const
{
if( QString::number( data->priority ).find( regExp ) != -1 ){
return true;
}else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
return true;
}else if(data->desc.find( regExp ) != -1 ){
return true;
}else if(data->sum.find( regExp ) != -1 ) {
return true;
}
return false;
}
bool OTodo::isCompleted() const
{
return data->isCompleted;
}
bool OTodo::hasDueDate() const
{
return data->hasDate;
}
bool OTodo::hasStartDate()const {
return data->start.isValid();
}
bool OTodo::hasCompletedDate()const {
return data->completed.isValid();
}
int OTodo::priority()const
{
return data->priority;
}
QString OTodo::summary() const
{
return data->sum;
}
ushort OTodo::progress() const
{
return data->prog;
}
QDate OTodo::dueDate()const
{
return data->date;
}
QDate OTodo::startDate()const {
return data->start;
}
QDate OTodo::completedDate()const {
return data->completed;
}
QString OTodo::description()const
{
return data->desc;
}
OPimState OTodo::state()const {
return data->state;
}
ORecur OTodo::recurrence()const {
return data->recur;
}
OPimMaintainer OTodo::maintainer()const {
return data->maintainer;
}
void OTodo::setCompleted( bool completed )
{
changeOrModify();
data->isCompleted = completed;
}
void OTodo::setHasDueDate( bool hasDate )
{
changeOrModify();
data->hasDate = hasDate;
}
void OTodo::setDescription(const QString &desc )
{
// qWarning( "desc " + desc );
changeOrModify();
data->desc = Qtopia::simplifyMultiLineSpace(desc );
}
void OTodo::setSummary( const QString& sum )
{
changeOrModify();
data->sum = sum;
}
void OTodo::setPriority(int prio )
{
changeOrModify();
data->priority = prio;
}
void OTodo::setDueDate( const QDate& date )
{
changeOrModify();
data->date = date;
}
void OTodo::setStartDate( const QDate& date ) {
changeOrModify();
data->start = date;
}
void OTodo::setCompletedDate( const QDate& date ) {
changeOrModify();
data->completed = date;
}
void OTodo::setState( const OPimState& state ) {
changeOrModify();
data->state = state;
}
void OTodo::setRecurrence( const ORecur& rec) {
changeOrModify();
data->recur = rec;
}
void OTodo::setMaintainer( const OPimMaintainer& pim ) {
changeOrModify();
data->maintainer = pim;
}
bool OTodo::isOverdue( )
{
if( data->hasDate && !data->isCompleted)
return QDate::currentDate() > data->date;
return false;
}
void OTodo::setProgress(ushort progress )
{
changeOrModify();
data->prog = progress;
}
QString OTodo::toShortText() const {
return summary();
}
/*!
Returns a richt text string
*/
QString OTodo::toRichText() const
{
QString text;
QStringList catlist;
// Description of the todo
if ( !summary().isEmpty() ) {
text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
}
if( !description().isEmpty() ){
text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
}
text += "<br><br><br>";
text += "<b>" + QObject::tr( "Priority:") +" </b>"
+ QString::number( priority() ) + " <br>";
text += "<b>" + QObject::tr( "Progress:") + " </b>"
+ QString::number( progress() ) + " %<br>";
if (hasDueDate() ){
text += "<b>" + QObject::tr( "Deadline:") + " </b>";
text += dueDate().toString();
text += "<br>";
}
text += "<b>" + QObject::tr( "Category:") + "</b> ";
text += categoryNames( "Todo List" ).join(", ");
text += "<br>";
return text;
}
OPimNotifyManager& OTodo::notifiers() {
return data->notifiers;
}
bool OTodo::operator<( const OTodo &toDoEvent )const{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() < toDoEvent.priority();
}else{
return dueDate() < toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator<=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() <= toDoEvent.priority();
}else{
return dueDate() <= toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator>(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator>=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator==(const OTodo &toDoEvent )const
{
if ( data->priority != toDoEvent.data->priority ) return false;
if ( data->priority != toDoEvent.data->prog ) return false;
if ( data->isCompleted != toDoEvent.data->isCompleted ) return false;
if ( data->hasDate != toDoEvent.data->hasDate ) return false;
if ( data->date != toDoEvent.data->date ) return false;
if ( data->sum != toDoEvent.data->sum ) return false;
if ( data->desc != toDoEvent.data->desc ) return false;
if ( data->maintainer != toDoEvent.data->maintainer )
return false;
return OPimRecord::operator==( toDoEvent );
}
void OTodo::deref() {
// qWarning("deref in ToDoEvent");
if ( data->deref() ) {
// qWarning("deleting");
delete data;
data= 0;
}
}
OTodo &OTodo::operator=(const OTodo &item )
{
+ if ( *this == item ) return *this;
+
OPimRecord::operator=( item );
//qWarning("operator= ref ");
item.data->ref();
deref();
data = item.data;
return *this;
}
QMap<int, QString> OTodo::toMap() const {
QMap<int, QString> map;
map.insert( Uid, QString::number( uid() ) );
map.insert( Category, idsToString( categories() ) );
map.insert( HasDate, QString::number( data->hasDate ) );
map.insert( Completed, QString::number( data->isCompleted ) );
map.insert( Description, data->desc );
map.insert( Summary, data->sum );
map.insert( Priority, QString::number( data->priority ) );
map.insert( DateDay, QString::number( data->date.day() ) );
map.insert( DateMonth, QString::number( data->date.month() ) );
map.insert( DateYear, QString::number( data->date.year() ) );
map.insert( Progress, QString::number( data->prog ) );
// map.insert( CrossReference, crossToString() );
/* FIXME!!! map.insert( State, );
map.insert( Recurrence, );
map.insert( Reminders, );
map.
*/
return map;
}
QMap<QString, QString> OTodo::toExtraMap()const {
return data->extra;
}
/**
* change or modify looks at the ref count and either
* creates a new QShared Object or it can modify it
* right in place
*/
void OTodo::changeOrModify() {
if ( data->count != 1 ) {
qWarning("changeOrModify");
data->deref();
OTodoData* d2 = new OTodoData();
copy(data, d2 );
data = d2;
}
}
// WATCHOUT
/*
* if you add something to the Data struct
* be sure to copy it here
*/
void OTodo::copy( OTodoData* src, OTodoData* dest ) {
dest->date = src->date;
dest->isCompleted = src->isCompleted;
dest->hasDate = src->hasDate;
dest->priority = src->priority;
dest->desc = src->desc;
dest->sum = src->sum;
dest->extra = src->extra;
dest->prog = src->prog;
dest->state = src->state;
dest->recur = src->recur;
dest->maintainer = src->maintainer;
dest->start = src->start;
dest->completed = src->completed;
dest->notifiers = src->notifiers;
}
QString OTodo::type() const {
return QString::fromLatin1("OTodo");
}
QString OTodo::recordField(int /*id*/ )const {
return QString::null;
}
int OTodo::rtti(){
return OPimResolver::TodoList;
}
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp
new file mode 100644
index 0000000..50cc032
--- a/dev/null
+++ b/libopie/pim/test/oevent_test.cpp
@@ -0,0 +1,23 @@
+#include <qdatetime.h>
+
+#include "../oevent.h"
+
+int main(int argc, char* argv ) {
+ OEvent ev;
+ ev.setUid( 20 );
+
+ ev.setDescription( "Foo" );
+
+ OEvent ev2 = ev;
+ ev2.setDescription("Foo2");
+ qWarning("%s", ev2.description().latin1() );
+ qWarning("%s", ev.description().latin1() );
+
+ QDateTime time = QDateTime::currentDateTime();
+ ev2.setStartDateTime( time );
+ ev2.setTimeZone( "Europe/London" );
+
+ qWarning("%s", ev2.startDateTime().toString().latin1() );
+ qWarning("%s", ev2.startDateTimeInZone().toString().latin1() );
+ return 0;
+}
diff --git a/libopie/pim/test/oevent_test.pro b/libopie/pim/test/oevent_test.pro
new file mode 100644
index 0000000..3365def
--- a/dev/null
+++ b/libopie/pim/test/oevent_test.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+#HEADERS =
+SOURCES = oevent_test.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopie
+TARGET = oevent_test
+
+include ( $(OPIEDIR)/include.pro ) \ No newline at end of file
diff --git a/libopie/pim/test/test_todo.cpp b/libopie/pim/test/test_todo.cpp
new file mode 100644
index 0000000..7440503
--- a/dev/null
+++ b/libopie/pim/test/test_todo.cpp
@@ -0,0 +1,36 @@
+#include <qdatetime.h>
+#include <qmap.h>
+
+#include <opie/otodo.h>
+#include <opie/otodoaccess.h>
+#include <opie/otodoaccessxml.h>
+
+int main(int argc, char* argv[] ) {
+
+ OTodoAccessXML* xml = new OTodoAccessXML("demo");
+ OTodoAccess ac(xml);
+ int elc;
+ QTime timer;
+ qWarning("start loading");
+ timer.start();
+ ac.load();
+ elc = timer.elapsed();
+ qWarning("Elapsed loading %d %d", elc, elc/1000);
+
+ timer.start();
+ OTodoAccess::List lis = ac.allRecords();
+ elc = timer.elapsed();
+ qWarning("Elapsed allRecords %d %d", elc, elc/1000 );
+ OTodoAccess::List::Iterator it;
+ timer.start();
+ac.save();
+/*
+ for( it = lis.begin(); it != lis.end(); ++it ) {
+ qWarning("Desc: " + (*it).summary() );
+ qWarning("UID %d", (*it).uid() );
+ }
+ */
+elc = timer.elapsed();
+
+ qWarning("elapsed iterating %d %d", elc, elc/1000 );
+};
diff --git a/libopie/pim/test/todo_test.pro b/libopie/pim/test/todo_test.pro
new file mode 100644
index 0000000..3d14dda
--- a/dev/null
+++ b/libopie/pim/test/todo_test.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+#HEADERS =
+SOURCES = test_todo.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopie -lopiesql
+TARGET = todo_test
+
+include ( $(OPIEDIR)/ ) \ No newline at end of file
diff --git a/libopie/tododb.cpp b/libopie/tododb.cpp
deleted file mode 100644
index 17163a0..0000000
--- a/libopie/tododb.cpp
+++ b/dev/null
@@ -1,268 +0,0 @@
-
-#include <qdir.h>
-#include <opie/tododb.h>
-#include <opie/xmltree.h>
-#include <opie/todoresource.h>
-#include <qpe/palmtoprecord.h>
-#include <qpe/global.h>
-
-using namespace Opie;
-
-namespace {
-
-class FileToDoResource : public ToDoResource {
-public:
- FileToDoResource() {};
- // FIXME better parsing
- bool save(const QString &name, const QValueList<ToDoEvent> &m_todos ){
- // prepare the XML
- XMLElement *tasks = new XMLElement( );
- tasks->setTagName("Tasks" );
- for( QValueList<ToDoEvent>::ConstIterator it = m_todos.begin(); it != m_todos.end(); ++it ){
- XMLElement::AttributeMap map;
- XMLElement *task = new XMLElement();
- map.insert( "Completed", QString::number((int)(*it).isCompleted() ) );
- map.insert( "HasDate", QString::number((int)(*it).hasDate() ) );
- map.insert( "Priority", QString::number( (*it).priority() ) );
- map.insert( "Progress", QString::number( (*it).progress() ) );
- map.insert( "Summary", (*it).summary() );
- QArray<int> arrat = (*it).categories();
- QString attr;
- for(uint i=0; i < arrat.count(); i++ ){
- attr.append(QString::number(arrat[i])+";" );
- }
- if(!attr.isEmpty() ) // remove the last ;
- attr.remove(attr.length()-1, 1 );
- map.insert( "Categories", attr );
- //else
- //map.insert( "Categories", QString::null );
- map.insert( "Description", (*it).description() );
- if( (*it).hasDate() ){
- map.insert("DateYear", QString::number( (*it).date().year() ) );
- map.insert("DateMonth", QString::number( (*it).date().month() ) );
- map.insert("DateDay", QString::number( (*it).date().day() ) );
- }
- map.insert("Uid", QString::number( (*it).uid() ) );
- task->setTagName("Task" );
- task->setAttributes( map );
- tasks->appendChild(task);
- }
- QFile file( name);
- if( file.open(IO_WriteOnly ) ){
- QTextStream stream(&file );
- stream.setEncoding( QTextStream::UnicodeUTF8 );
- stream << "<!DOCTYPE Tasks>" << endl;
- tasks->save(stream );
- delete tasks;
- stream << "</Tasks>" << endl;
- file.close();
- return true;
- }
- return false;
- }
- QValueList<ToDoEvent> load( const QString &name ){
- qWarning("loading tododb" );
- QValueList<ToDoEvent> m_todos;
- XMLElement *root = XMLElement::load( name );
- if(root != 0l ){ // start parsing
- qWarning("ToDoDB::load tagName(): %s", root->tagName().latin1() );
- //if( root->tagName() == QString::fromLatin1("Tasks" ) ){// Start
- XMLElement *element = root->firstChild();
- if (element == 0 )
- return m_todos;
- element = element->firstChild();
- while( element ){
- if( element->tagName() != QString::fromLatin1("Task") ){
- element = element->nextChild();
- continue;
- }
- qWarning("ToDoDB::load element tagName() : %s", element->tagName().latin1() );
- QString dummy;
- ToDoEvent event;
- bool ok;
- int dumInt;
- // completed
- dummy = element->attribute("Completed" );
- dumInt = dummy.toInt(&ok );
- if(ok ) event.setCompleted( dumInt == 0 ? false : true );
- // progress
- dummy = element->attribute("Progress" );
- {
- ushort dumShort = dummy.toUShort(&ok);
- event.setProgress( dumShort );
-
- }
- // hasDate
- dummy = element->attribute("HasDate" );
- dumInt = dummy.toInt(&ok );
- if(ok ) event.setHasDate( dumInt == 0 ? false: true );
- // set the date
- bool hasDa = dumInt;
- if ( hasDa ) { //parse the date
- int year, day, month = 0;
- year = day = month;
- // year
- dummy = element->attribute("DateYear" );
- dumInt = dummy.toInt(&ok );
- if( ok ) year = dumInt;
- // month
- dummy = element->attribute("DateMonth" );
- dumInt = dummy.toInt(&ok );
- if(ok ) month = dumInt;
- dummy = element->attribute("DateDay" );
- dumInt = dummy.toInt(&ok );
- if(ok ) day = dumInt;
- // set the date
- QDate date( year, month, day );
- event.setDate( date);
- }
- dummy = element->attribute("Priority" );
- dumInt = dummy.toInt(&ok );
- if(!ok ) dumInt = ToDoEvent::NORMAL;
- event.setPriority( dumInt );
- //description
- dummy = element->attribute("Description" );
- event.setDescription( dummy );
- dummy = element->attribute("Summary" );
- event.setSummary( dummy );
- // category
- dummy = element->attribute("Categories" );
- QStringList ids = QStringList::split(";", dummy );
- event.setCategories( ids );
-
- //uid
- dummy = element->attribute("Uid" );
- dumInt = dummy.toInt(&ok );
- if(ok ) event.setUid( dumInt );
- m_todos.append( event );
- element = element->nextChild(); // next element
- }
- //}
- }else {
- qWarning("could not load" );
- }
- delete root;
- qWarning("returning" );
- return m_todos;
- }
-};
-
-}
-
-ToDoDB::ToDoDB(const QString &fileName, ToDoResource *res ){
- m_fileName = fileName;
- if( fileName.isEmpty() && res == 0 ){
- m_fileName = Global::applicationFileName("todolist","todolist.xml");
- res = new FileToDoResource();
- //qWarning("%s", m_fileName.latin1() );
- }else if(res == 0 ){ // let's create a ToDoResource for xml
- res = new FileToDoResource();
- }
- m_res = res;
- load();
-}
-ToDoResource* ToDoDB::resource(){
- return m_res;
-};
-void ToDoDB::setResource( ToDoResource *res )
-{
- delete m_res;
- m_res = res;
-}
-ToDoDB::~ToDoDB()
-{
- delete m_res;
-}
-QValueList<ToDoEvent> ToDoDB::effectiveToDos(const QDate &from, const QDate &to,
- bool all )
-{
- QValueList<ToDoEvent> events;
- for( QValueList<ToDoEvent>::Iterator it = m_todos.begin(); it!= m_todos.end(); ++it ){
- if( (*it).hasDate() ){
- if( (*it).date() >= from && (*it).date() <= to )
- events.append( (*it) );
- }else if( all ){
- events.append( (*it) );
- }
- }
- return events;
-}
-QValueList<ToDoEvent> ToDoDB::effectiveToDos(const QDate &from,
- bool all)
-{
- return effectiveToDos( from, QDate::currentDate(), all );
-}
-QValueList<ToDoEvent> ToDoDB::overDue()
-{
- QValueList<ToDoEvent> events;
- for( QValueList<ToDoEvent>::Iterator it = m_todos.begin(); it!= m_todos.end(); ++it ){
- if( (*it).isOverdue() )
- events.append((*it) );
- }
- return events;
-}
-QValueList<ToDoEvent> ToDoDB::rawToDos()
-{
- return m_todos;
-}
-void ToDoDB::addEvent( const ToDoEvent &event )
-{
- m_todos.append( event );
-}
-void ToDoDB::editEvent( const ToDoEvent &event )
-{
- m_todos.remove( event );
- m_todos.append( event );
-}
-void ToDoDB::removeEvent( const ToDoEvent &event )
-{
- m_todos.remove( event );
-}
-void ToDoDB::replaceEvent(const ToDoEvent &event )
-{
- QValueList<ToDoEvent>::Iterator it;
- int uid = event.uid();
- // == is not overloaded as we would like :( so let's search for the uid
- for(it = m_todos.begin(); it != m_todos.end(); ++it ){
- if( (*it).uid() == uid ){
- m_todos.remove( (*it) );
- break; // should save us the iterate is now borked
- }
- }
- m_todos.append(event);
-}
-void ToDoDB::reload()
-{
- load();
-}
-void ToDoDB::mergeWith(const QValueList<ToDoEvent>& events )
-{
- QValueList<ToDoEvent>::ConstIterator it;
- for( it = events.begin(); it != events.end(); ++it ){
- replaceEvent( (*it) );
- }
-}
-void ToDoDB::setFileName(const QString &file )
-{
- m_fileName =file;
-}
-QString ToDoDB::fileName()const
-{
- return m_fileName;
-}
-void ToDoDB::load()
-{
- m_todos = m_res->load( m_fileName );
-}
-bool ToDoDB::save()
-{
- return m_res->save( m_fileName, m_todos );
-}
-
-
-
-
-
-
-
-
diff --git a/libopie/tododb.h b/libopie/tododb.h
deleted file mode 100644
index 7fd9f96..0000000
--- a/libopie/tododb.h
+++ b/dev/null
@@ -1,46 +0,0 @@
-
-#ifndef tododb_h
-#define tododb_h
-
-#include <qvaluelist.h>
-
-#include <opie/todoevent.h>
-
-class ToDoResource;
-class ToDoDB
-{
- public:
- // if no argument is supplied pick the default book
- ToDoDB(const QString &fileName = QString::null, ToDoResource* resource= 0 );
- ~ToDoDB();
- QValueList<ToDoEvent> effectiveToDos(const QDate &from,
- const QDate &to,
- bool includeNoDates = true);
- QValueList<ToDoEvent> effectiveToDos(const QDate &start, bool includeNoDates = true );
- QValueList<ToDoEvent> rawToDos(); // all events
- QValueList<ToDoEvent> overDue();
-
- void addEvent(const ToDoEvent &event );
- void editEvent(const ToDoEvent &editEvent );
- void removeEvent(const ToDoEvent &event);
- void replaceEvent(const ToDoEvent &event );
- // QValueList<ToDoEvents will overwrite existing ones no smart code at all ;)
- void mergeWith(const QValueList<ToDoEvent>& );
- void reload();
- void setFileName(const QString & );
- QString fileName()const;
- bool save();
- ToDoResource *resource();
- void setResource(ToDoResource* res);
-
- private:
- class ToDoDBPrivate;
- ToDoDBPrivate *d;
- QString m_fileName;
- ToDoResource *m_res;
- QValueList<ToDoEvent> m_todos;
- void load();
-};
-
-
-#endif
diff --git a/libopie/todoevent.cpp b/libopie/todoevent.cpp
deleted file mode 100644
index f744550..0000000
--- a/libopie/todoevent.cpp
+++ b/dev/null
@@ -1,339 +0,0 @@
-
-#include <opie/todoevent.h>
-
-
-#include <qpe/palmtopuidgen.h>
-#include <qpe/stringutil.h>
-#include <qpe/palmtoprecord.h>
-
-#include <qpe/stringutil.h>
-#include <qpe/categories.h>
-#include <qpe/categoryselect.h>
-
-#include <qobject.h>
-
-ToDoEvent::ToDoEvent(const ToDoEvent &event )
-{
- *this = event;
-}
-
-ToDoEvent::ToDoEvent(bool completed, int priority,
- const QStringList &category,
- const QString& summary,
- const QString &description,
- ushort progress,
- bool hasDate, QDate date, int uid )
-{
- m_date = date;
- m_isCompleted = completed;
- m_hasDate = hasDate;
- m_priority = priority;
- m_category = category;
- m_sum = summary;
- m_prog = progress;
- m_desc = Qtopia::simplifyMultiLineSpace(description );
- if (uid == -1 ) {
- Qtopia::UidGen *uidgen = new Qtopia::UidGen();
- uid = uidgen->generate();
- delete uidgen;
- }// generate the ids
- m_uid = uid;
-}
-QArray<int> ToDoEvent::categories()const
-{
- QArray<int> array(m_category.count() ); // currently the datebook can be only in one category
- array = Qtopia::Record::idsFromString( m_category.join(";") );
- return array;
-}
-bool ToDoEvent::match( const QRegExp &regExp )const
-{
- if( QString::number( m_priority ).find( regExp ) != -1 ){
- return true;
- }else if( m_hasDate && m_date.toString().find( regExp) != -1 ){
- return true;
- }else if(m_desc.find( regExp ) != -1 ){
- return true;
- }
- return false;
-}
-bool ToDoEvent::isCompleted() const
-{
- return m_isCompleted;
-}
-bool ToDoEvent::hasDate() const
-{
- return m_hasDate;
-}
-int ToDoEvent::priority()const
-{
- return m_priority;
-}
-QStringList ToDoEvent::allCategories()const
-{
- return m_category;
-}
-QString ToDoEvent::extra(const QString& )const
-{
- return QString::null;
-}
-QString ToDoEvent::summary() const
-{
- return m_sum;
-}
-ushort ToDoEvent::progress() const
-{
- return m_prog;
-}
-QStringList ToDoEvent::relatedApps() const
-{
- QStringList list;
- QMap<QString, QArray<int> >::ConstIterator it;
- for ( it = m_relations.begin(); it != m_relations.end(); ++it ) {
- list << it.key();
- }
- return list;
-}
-QArray<int> ToDoEvent::relations( const QString& app)const
-{
- QArray<int> tmp;
- QMap<QString, QArray<int> >::ConstIterator it;
- it = m_relations.find( app);
- if ( it != m_relations.end() )
- tmp = it.data();
- return tmp;
-}
-void ToDoEvent::insertCategory(const QString &str )
-{
- m_category.append( str );
-}
-void ToDoEvent::clearCategories()
-{
- m_category.clear();
-}
-void ToDoEvent::setCategories(const QStringList &list )
-{
- m_category = list;
-}
-QDate ToDoEvent::date()const
-{
- return m_date;
-}
-
-QString ToDoEvent::description()const
-{
- return m_desc;
-}
-void ToDoEvent::setCompleted( bool completed )
-{
- m_isCompleted = completed;
-}
-void ToDoEvent::setHasDate( bool hasDate )
-{
- m_hasDate = hasDate;
-}
-void ToDoEvent::setDescription(const QString &desc )
-{
- m_desc = Qtopia::simplifyMultiLineSpace(desc );
-}
-void ToDoEvent::setExtra( const QString&, const QString& )
-{
-
-}
-void ToDoEvent::setSummary( const QString& sum )
-{
- m_sum = sum;
-}
-void ToDoEvent::setCategory( const QString &cat )
-{
- qWarning("setCategory %s", cat.latin1() );
- m_category.clear();
- m_category << cat;
-}
-void ToDoEvent::setPriority(int prio )
-{
- m_priority = prio;
-}
-void ToDoEvent::setDate( QDate date )
-{
- m_date = date;
-}
-void ToDoEvent::addRelated( const QString &app, int id )
-{
- QMap<QString, QArray<int> >::Iterator it;
- QArray<int> tmp;
- it = m_relations.find( app );
- if ( it == m_relations.end() ) {
- tmp.resize(1 );
- tmp[0] = id;
- }else{
- tmp = it.data();
- tmp.resize( tmp.size() + 1 );
- tmp[tmp.size() - 1] = id;
- }
- m_relations.replace( app, tmp );
-}
-void ToDoEvent::addRelated(const QString& app, QArray<int> ids )
-{
- QMap<QString, QArray<int> >::Iterator it;
- QArray<int> tmp;
- it = m_relations.find( app);
- if ( it == m_relations.end() ) { // not there
- /** tmp.resize( ids.size() ); stupid??
- */
- tmp = ids;
- }else{
- tmp = it.data();
- int offset = tmp.size()-1;
- tmp.resize( tmp.size() + ids.size() );
- for (uint i = 0; i < ids.size(); i++ ) {
- tmp[offset+i] = ids[i];
- }
-
- }
- m_relations.replace( app, tmp );
-}
-void ToDoEvent::clearRelated( const QString& app )
-{
- m_relations.remove( app );
-}
-bool ToDoEvent::isOverdue( )
-{
- if( m_hasDate )
- return QDate::currentDate() > m_date;
- return false;
-}
-void ToDoEvent::setProgress(ushort progress )
-{
- m_prog = progress;
-}
-/*!
- Returns a richt text string
-*/
-QString ToDoEvent::richText() const
-{
- QString text;
- QStringList catlist;
-
- // Description of the todo
- if ( !description().isEmpty() ){
- text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
- text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
- text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
- text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br><br><br>";
- }
- text += "<b>" + QObject::tr( "Priority:") +" </b>"
- + QString::number( priority() ) + " <br>";
- text += "<b>" + QObject::tr( "Progress:") + " </b>"
- + QString::number( progress() ) + " %<br>";
- if (hasDate() ){
- text += "<b>" + QObject::tr( "Deadline:") + " </b>";
- text += date().toString();
- text += "<br>";
- }
-
- // Open database of all categories and get the list of
- // the categories this todoevent belongs to.
- // Then print them...
- // I am not sure whether there is no better way doing this !?
- Categories catdb;
- bool firstloop = true;
- catdb.load( categoryFileName() );
- catlist = allCategories();
-
- text += "<b>" + QObject::tr( "Category:") + "</b> ";
- for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) {
- if (!firstloop){
- text += ", ";
- }
- firstloop = false;
- text += catdb.label ("todo", (*it).toInt());
- }
- text += "<br>";
- return text;
-}
-
-bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{
- if( !hasDate() && !toDoEvent.hasDate() ) return true;
- if( !hasDate() && toDoEvent.hasDate() ) return false;
- if( hasDate() && toDoEvent.hasDate() ){
- if( date() == toDoEvent.date() ){ // let's the priority decide
- return priority() < toDoEvent.priority();
- }else{
- return date() < toDoEvent.date();
- }
- }
- return false;
-}
-bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const
-{
- if( !hasDate() && !toDoEvent.hasDate() ) return true;
- if( !hasDate() && toDoEvent.hasDate() ) return true;
- if( hasDate() && toDoEvent.hasDate() ){
- if( date() == toDoEvent.date() ){ // let's the priority decide
- return priority() <= toDoEvent.priority();
- }else{
- return date() <= toDoEvent.date();
- }
- }
- return true;
-}
-bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const
-{
- if( !hasDate() && !toDoEvent.hasDate() ) return false;
- if( !hasDate() && toDoEvent.hasDate() ) return false;
- if( hasDate() && toDoEvent.hasDate() ){
- if( date() == toDoEvent.date() ){ // let's the priority decide
- return priority() > toDoEvent.priority();
- }else{
- return date() > toDoEvent.date();
- }
- }
- return false;
-}
-bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const
-{
- if( !hasDate() && !toDoEvent.hasDate() ) return true;
- if( !hasDate() && toDoEvent.hasDate() ) return false;
- if( hasDate() && toDoEvent.hasDate() ){
- if( date() == toDoEvent.date() ){ // let's the priority decide
- return priority() > toDoEvent.priority();
- }else{
- return date() > toDoEvent.date();
- }
- }
- return true;
-}
-bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const
-{
- if( m_priority == toDoEvent.m_priority &&
- m_priority == toDoEvent.m_prog &&
- m_isCompleted == toDoEvent.m_isCompleted &&
- m_hasDate == toDoEvent.m_hasDate &&
- m_date == toDoEvent.m_date &&
- m_category == toDoEvent.m_category &&
- m_sum == toDoEvent.m_sum &&
- m_desc == toDoEvent.m_desc )
- return true;
- return false;
-}
-ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item )
-{
- m_date = item.m_date;
- m_isCompleted = item.m_isCompleted;
- m_hasDate = item.m_hasDate;
- m_priority = item.m_priority;
- m_category = item.m_category;
- m_desc = item.m_desc;
- m_uid = item.m_uid;
- m_sum = item.m_sum;
- m_prog = item.m_prog;
- return *this;
-}
-
-
-
-
-
-
-
-
diff --git a/libopie/todoevent.h b/libopie/todoevent.h
deleted file mode 100644
index b55a39b..0000000
--- a/libopie/todoevent.h
+++ b/dev/null
@@ -1,191 +0,0 @@
-
-#ifndef todoevent_h
-#define todoevent_h
-
-
-#include <qarray.h>
-#include <qmap.h>
-#include <qregexp.h>
-#include <qstringlist.h>
-#include <qdatetime.h>
-
-
-class ToDoEvent {
- friend class ToDoDB;
- public:
- // priorities from Very low to very high
- enum Priority { VERYHIGH=1, HIGH, NORMAL, LOW, VERYLOW };
- /* Constructs a new ToDoEvent
- @param completed Is the TodoEvent completed
- @param priority What is the priority of this ToDoEvent
- @param category Which category does it belong( uid )
- @param summary A small summary of the todo
- @param description What is this ToDoEvent about
- @param hasDate Does this Event got a deadline
- @param date what is the deadline?
- @param uid what is the UUID of this Event
- **/
- ToDoEvent( bool completed = false, int priority = NORMAL,
- const QStringList &category = QStringList(),
- const QString &summary = QString::null ,
- const QString &description = QString::null,
- ushort progress = 0,
- bool hasDate = false, QDate date = QDate::currentDate(), int uid = -1 );
- /* Copy c'tor
-
- **/
- ToDoEvent(const ToDoEvent & );
-
- /*
- Is this event completed?
- **/
- bool isCompleted() const;
-
- /*
- Does this Event have a deadline
- **/
- bool hasDate() const;
-
- /*
- What is the priority?
- **/
- int priority()const ;
-
- /**
- * progress as ushort 0, 20, 40, 60, 80 or 100%
- */
- ushort progress() const;
- /*
- All category numbers as QString in a List
- **/
- QStringList allCategories()const;
-
- /*
- * Same as above but with QArray<int>
- */
- QArray<int> categories() const;
-
- /**
- * The end Date
- */
- QDate date()const;
-
- /**
- * The description of the todo
- */
- QString description()const;
-
- /**
- * A small summary of the todo
- */
- QString summary() const;
-
- /**
- * Return this todoevent in a RichText formatted QString
- */
- QString richText() const;
-
- /**
- * Returns the UID of the Todo
- */
- int uid()const { return m_uid;};
-
-
- QString extra(const QString& )const;
-
- /**
- * returns a list of apps which have related items
- */
- QStringList relatedApps()const;
-
- /**
- * returns all relations for one app
- */
- QArray<int> relations( const QString& app )const;
- /**
- * Set if this Todo is completed
- */
- void setCompleted(bool completed );
-
- /**
- * set if this todo got an end data
- */
- void setHasDate( bool hasDate );
- // if the category doesn't exist we will create it
- // this sets the the Category after this call category will be the only category
- void setCategory( const QString &category );
- // adds a category to the Categories of this event
- void insertCategory(const QString &category );
-
- /**
- * Removes this event from all categories
- */
- void clearCategories();
-
- /**
- * This todo belongs to xxx categories
- */
- void setCategories(const QStringList& );
-
- /**
- * Set the priority of the Todo
- */
- void setPriority(int priority );
-
- /**
- * Set the progress.
- */
- void setProgress( ushort progress );
-
- /**
- * add related function it replaces too ;)
- */
- void addRelated( const QString& app, int id );
-
- /**
- * add related
- */
- void addRelated( const QString& app, QArray<int> ids );
-
- /**
- * clear relations for one app
- */
- void clearRelated(const QString& app);
-
- /**
- * set the end date
- */
- void setDate( QDate date );
- void setDescription(const QString& );
- void setSummary(const QString& );
- void setExtra( const QString&, const QString& );
- bool isOverdue();
-
- bool match( const QRegExp &r )const;
-
- void setUid(int id) {m_uid = id; };
- bool operator<(const ToDoEvent &toDoEvent )const;
- bool operator<=(const ToDoEvent &toDoEvent )const;
- bool operator!=(const ToDoEvent &toDoEvent )const { return !(*this == toDoEvent); };
- bool operator>(const ToDoEvent &toDoEvent )const;
- bool operator>=(const ToDoEvent &toDoEvent)const;
- bool operator==(const ToDoEvent &toDoEvent )const;
- ToDoEvent &operator=(const ToDoEvent &toDoEvent );
- private:
- class ToDoEventPrivate;
- ToDoEventPrivate *d;
- QDate m_date;
- bool m_isCompleted:1;
- bool m_hasDate:1;
- int m_priority;
- QStringList m_category;
- QString m_desc;
- QString m_sum;
- QMap<QString, QString> m_extra;
- QMap<QString, QArray<int> > m_relations;
- int m_uid;
- ushort m_prog;
-};
-
-
-#endif
diff --git a/libopie/todoresource.h b/libopie/todoresource.h
deleted file mode 100644
index 34edb04..0000000
--- a/libopie/todoresource.h
+++ b/dev/null
@@ -1,14 +0,0 @@
-
-
-#ifndef opietodoresource_h
-#define opietodoresource_h
-
-class ToDoEvent;
-class ToDoResource {
- public:
- ToDoResource( ) {};
- virtual QValueList<ToDoEvent> load(const QString &file ) = 0;
- virtual bool save( const QString &file, const QValueList<ToDoEvent> & ) = 0;
-};
-
-#endif
diff --git a/libopie/todovcalresource.cpp b/libopie/todovcalresource.cpp
deleted file mode 100644
index 1df5aff..0000000
--- a/libopie/todovcalresource.cpp
+++ b/dev/null
@@ -1,158 +0,0 @@
-/*
-               =. This file is part of the OPIE Project
-             .=l. Copyright (c) 2002 Holger Freyther <freyther@kde.org>
-           .>+-= the use of vobject was inspired by libkcal
- _;:,     .>    :=|. This library is free software; you can
-.> <`_,   >  .   <= redistribute it and/or modify it under
-:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
-.="- .-=="i,     .._ License as published by the Free Software
- - .   .-<_>     .<> Foundation; either version 2 of the License,
-     ._= =}       : or (at your option) any later version.
-    .%`+i>       _;_.
-    .i_,=:_.      -<s. This library is distributed in the hope that
-     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
-    : ..    .:,     . . . without even the implied warranty of
-    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
-  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
-..}^=.=       =       ; Library General Public License for more
-++=   -.     .`     .: details.
- :     =  ...= . :.=-
- -.   .:....=;==+<; You should have received a copy of the GNU
-  -_. . .   )=.  = Library General Public License along with
-    --        :-=` this library; see the file COPYING.LIB.
- If not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
-*/
-
-#include <qfile.h>
-#include <qvaluelist.h>
-#include <opie/todoevent.h>
-#include <opie/todovcalresource.h>
-
-#include "../library/backend/vobject_p.h"
-#include "../library/timeconversion.h"
-#include "../library/backend/qfiledirect_p.h"
-
-static VObject *vobjByEvent( const ToDoEvent &event )
-{
- VObject *task = newVObject( VCTodoProp );
- if( task == 0 )
- return 0l;
- if( event.hasDate() )
- addPropValue( task, VCDueProp, TimeConversion::toISO8601( event.date() ) );
-
- if( event.isCompleted() )
- addPropValue( task, VCStatusProp, "COMPLETED");
-
- QString string = QString::number(event.priority() );
- addPropValue( task, VCPriorityProp, string.local8Bit() );
- addPropValue( task, VCCategoriesProp, event.allCategories().join(";").local8Bit() );
- addPropValue( task, VCDescriptionProp, event.description().local8Bit() );
- addPropValue( task, VCSummaryProp, event.summary().left(15).local8Bit() );
- return task;
-};
-
-static ToDoEvent eventByVObj( VObject *obj ){
- ToDoEvent event;
- VObject *ob;
- QCString name;
- // no uid, attendees, ... and no fun
- // description
- if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){
- name = vObjectStringZValue( ob );
- event.setDescription( name );
- }
- // summary
- if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) {
- name = vObjectStringZValue( ob );
- event.setSummary( name );
- }
- // completed
- if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){
- name = vObjectStringZValue( ob );
- if( name == "COMPLETED" ){
- event.setCompleted( true );
- }else{
- event.setCompleted( false );
- }
- }else
- event.setCompleted( false );
- // priority
- if ((ob = isAPropertyOf(obj, VCPriorityProp))) {
- name = vObjectStringZValue( ob );
- bool ok;
- event.setPriority(name.toInt(&ok) );
- }
- //due date
- if((ob = isAPropertyOf(obj, VCDueProp)) ){
- event.setHasDate( true );
- name = vObjectStringZValue( ob );
- event.setDate( TimeConversion::fromISO8601( name).date() );
- }
- // categories
- if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){
- name = vObjectStringZValue( ob );
- qWarning("Categories:%s", name.data() );
- }
-
- return event;
-};
-
-
-QValueList<ToDoEvent> ToDoVCalResource::load(const QString &file)
-{
- QValueList<ToDoEvent> events;
- VObject *vcal = 0l;
- vcal = Parse_MIME_FromFileName( (char *)file.utf8().data() ); // from vobject
- if(!vcal )
- return events;
- // start parsing
-
- VObjectIterator it;
- VObject *vobj;
- initPropIterator(&it, vcal);
-
- while( moreIteration( &it ) ) {
- vobj = ::nextVObject( &it );
- QCString name = ::vObjectName( vobj );
- //QCString objVal = ::vObjectStringZValue( vobj );
- // let's find out the type
- if( name == VCTodoProp ){
- events.append( eventByVObj( vobj ) );
-
- } // parse the value
- }
- return events;
-}
-bool ToDoVCalResource::save(const QString &fileName, const QValueList<ToDoEvent>&list )
-{
- QFileDirect file ( fileName );
- if(!file.open(IO_WriteOnly ) )
- return false;
- // obj
- VObject *obj;
- obj = newVObject( VCCalProp );
- addPropValue( obj, VCVersionProp, "1.0" );
- VObject *vo;
- for(QValueList<ToDoEvent>::ConstIterator it = list.begin(); it != list.end(); ++it ){
- vo = vobjByEvent( (*it) );
- addVObjectProp(obj, vo );
- }
- writeVObject( file.directHandle(), obj );
- cleanVObject( obj );
- cleanStrTbl();
-
- return true;
-}
-
-
-
-
-
-
-
-
-
-
diff --git a/libopie/todovcalresource.h b/libopie/todovcalresource.h
deleted file mode 100644
index 0663bc2..0000000
--- a/libopie/todovcalresource.h
+++ b/dev/null
@@ -1,42 +0,0 @@
-/*
-               =. This file is part of the OPIE Project
-             .=l. Copyright (c) 2002 Holger Freyther <freyther@kde.org>
-           .>+-=
- _;:,     .>    :=|. This library is free software; you can
-.> <`_,   >  .   <= redistribute it and/or modify it under
-:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
-.="- .-=="i,     .._ License as published by the Free Software
- - .   .-<_>     .<> Foundation; either version 2 of the License,
-     ._= =}       : or (at your option) any later version.
-    .%`+i>       _;_.
-    .i_,=:_.      -<s. This library is distributed in the hope that
-     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
-    : ..    .:,     . . . without even the implied warranty of
-    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
-  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
-..}^=.=       =       ; Library General Public License for more
-++=   -.     .`     .: details.
- :     =  ...= . :.=-
- -.   .:....=;==+<; You should have received a copy of the GNU
-  -_. . .   )=.  = Library General Public License along with
-    --        :-=` this library; see the file COPYING.LIB.
- If not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
-*/
-
-#ifndef opievcaltodoresource_h
-#define opievcaltodoresource_h
-
-#include <opie/todoresource.h>
-
-class ToDoVCalResource : public ToDoResource {
- public:
- ToDoVCalResource() { };
- QValueList<ToDoEvent> load(const QString &file );
- bool save( const QString &filename, const QValueList<ToDoEvent> & );
-
-};
-
-#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
index 622d40a..e537269 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
@@ -1,461 +1,470 @@
/*
* VCard Backend for the OPIE-Contact Database.
*
* Copyright (C) 2000 Trolltech AS. All rights reserved.
* Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* =====================================================================
* ToDo:
*
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.8 2003/02/21 16:52:49 zecke
+ * -Remove old Todo classes they're deprecated and today I already using the
+ * new API
+ * -Guard against self assignment in OTodo
+ * -Add test apps for OPIM
+ * -Opiefied Event classes
+ * -Added TimeZone handling and pinning of TimeZones to OEvent
+ * -Adjust ORecur and the widget to better timezone behaviour
+ *
* Revision 1.7 2003/02/16 22:25:46 zecke
* 0000276 Fix for that bug.. or better temp workaround
* A Preferred Number is HOME|VOICE
* A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test
* triggers both
* and the cell phone number overrides the other entries..
*
* as a temp I check that it's not equal to HOME|VOICE|CELL before setting the
* number
*
* The right and final fix would be to reorder the if statement to make it
* if else based and the less common thing put to the bottom
*
* OTodoAccessVcal fix the date for beaming
*
* Revision 1.6 2003/01/13 15:49:31 eilers
* Fixing crash when businesscard.vcf is missing..
*
* Revision 1.5 2002/12/07 13:26:22 eilers
* Fixing bug in storing anniversary..
*
* Revision 1.4 2002/11/13 14:14:51 eilers
* Added sorted for Contacts..
*
* Revision 1.3 2002/11/11 16:41:09 kergoth
* no default arguments in implementation
*
* Revision 1.2 2002/11/10 15:41:53 eilers
* Bugfixes..
*
* Revision 1.1 2002/11/09 14:34:52 eilers
* Added VCard Backend.
*
*/
#include "ocontactaccessbackend_vcard.h"
#include "../../library/backend/vobject_p.h"
#include "../../library/backend/qfiledirect_p.h"
#include <qpe/timeconversion.h>
#include <qfile.h>
OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ):
m_dirty( false ),
m_file( filename )
{
load();
}
bool OContactAccessBackend_VCard::load ()
{
m_map.clear();
m_dirty = false;
VObject* obj = 0l;
- if ( QFile( m_file ).exists() ){
+ if ( QFile::exists(m_file) ){
obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
if ( !obj )
return false;
}else{
qWarning("File \"%s\" not found !", m_file.latin1() );
return false;
}
while ( obj ) {
OContact con = parseVObject( obj );
/*
* if uid is 0 assign a new one
* this at least happens on
* Nokia6210
*/
if ( con.uid() == 0 ){
con.setUid( 1 );
qWarning("assigned new uid %d",con.uid() );
}
m_map.insert( con.uid(), con );
VObject *t = obj;
obj = nextVObjectInList(obj);
cleanVObject( t );
}
return true;
}
bool OContactAccessBackend_VCard::reload()
{
return load();
}
bool OContactAccessBackend_VCard::save()
{
if (!m_dirty )
return true;
QFileDirect file( m_file );
if (!file.open(IO_WriteOnly ) )
return false;
VObject *obj;
obj = newVObject( VCCalProp );
addPropValue( obj, VCVersionProp, "1.0" );
VObject *vo;
for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
vo = createVObject( *it );
writeVObject( file.directHandle() , vo );
cleanVObject( vo );
}
cleanStrTbl();
m_dirty = false;
return true;
}
void OContactAccessBackend_VCard::clear ()
{
m_map.clear();
m_dirty = true; // ??? sure ? (se)
}
bool OContactAccessBackend_VCard::add ( const OContact& newcontact )
{
m_map.insert( newcontact.uid(), newcontact );
m_dirty = true;
return true;
}
bool OContactAccessBackend_VCard::remove ( int uid )
{
m_map.remove( uid );
m_dirty = true;
return true;
}
bool OContactAccessBackend_VCard::replace ( const OContact &contact )
{
m_map.replace( contact.uid(), contact );
m_dirty = true;
return true;
}
OContact OContactAccessBackend_VCard::find ( int uid ) const
{
return m_map[uid];
}
QArray<int> OContactAccessBackend_VCard::allRecords() const
{
QArray<int> ar( m_map.count() );
QMap<int, OContact>::ConstIterator it;
int i = 0;
for ( it = m_map.begin(); it != m_map.end(); ++it ) {
ar[i] = it.key();
i++;
}
return ar;
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int )
{
QArray<int> ar(0);
return ar;
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
{
QArray<int> ar(0);
return ar;
}
const uint OContactAccessBackend_VCard::querySettings()
{
return 0; // No search possible
}
bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const
{
return false; // No search possible, therefore all settings invalid ;)
}
bool OContactAccessBackend_VCard::wasChangedExternally()
{
return false; // Don't expect concurrent access
}
// Not implemented
QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int )
{
QArray<int> ar(0);
return ar;
}
// *** Private stuff ***
OContact OContactAccessBackend_VCard::parseVObject( VObject *obj )
{
OContact c;
VObjectIterator it;
initPropIterator( &it, obj );
while( moreIteration( &it ) ) {
VObject *o = nextVObject( &it );
QCString name = vObjectName( o );
QCString value = vObjectStringZValue( o );
if ( name == VCNameProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
QString value = vObjectStringZValue( o );
if ( name == VCNamePrefixesProp )
c.setTitle( value );
else if ( name == VCNameSuffixesProp )
c.setSuffix( value );
else if ( name == VCFamilyNameProp )
c.setLastName( value );
else if ( name == VCGivenNameProp )
c.setFirstName( value );
else if ( name == VCAdditionalNamesProp )
c.setMiddleName( value );
}
}
else if ( name == VCAdrProp ) {
bool work = TRUE; // default address is work address
QString street;
QString city;
QString region;
QString postal;
QString country;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
if ( name == VCHomeProp )
work = FALSE;
else if ( name == VCWorkProp )
work = TRUE;
else if ( name == VCStreetAddressProp )
street = value;
else if ( name == VCCityProp )
city = value;
else if ( name == VCRegionProp )
region = value;
else if ( name == VCPostalCodeProp )
postal = value;
else if ( name == VCCountryNameProp )
country = value;
}
if ( work ) {
c.setBusinessStreet( street );
c.setBusinessCity( city );
c.setBusinessCountry( country );
c.setBusinessZip( postal );
c.setBusinessState( region );
} else {
c.setHomeStreet( street );
c.setHomeCity( city );
c.setHomeCountry( country );
c.setHomeZip( postal );
c.setHomeState( region );
}
}
else if ( name == VCTelephoneProp ) {
enum {
HOME = 0x01,
WORK = 0x02,
VOICE = 0x04,
CELL = 0x08,
FAX = 0x10,
PAGER = 0x20,
UNKNOWN = 0x80
};
int type = 0;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name == VCHomeProp )
type |= HOME;
else if ( name == VCWorkProp )
type |= WORK;
else if ( name == VCVoiceProp )
type |= VOICE;
else if ( name == VCCellularProp )
type |= CELL;
else if ( name == VCFaxProp )
type |= FAX;
else if ( name == VCPagerProp )
type |= PAGER;
else if ( name == VCPreferredProp )
;
else
type |= UNKNOWN;
}
if ( (type & UNKNOWN) != UNKNOWN ) {
if ( ( type & (HOME|WORK) ) == 0 ) // default
type |= HOME;
if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
type |= VOICE;
qWarning("value %s %d", value.data(), type );
if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) )
c.setHomePhone( value );
if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
c.setHomeFax( value );
if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
c.setHomeMobile( value );
if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) )
c.setBusinessPhone( value );
if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
c.setBusinessFax( value );
if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
c.setBusinessMobile( value );
if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
c.setBusinessPager( value );
}
}
else if ( name == VCEmailAddressProp ) {
QString email = vObjectStringZValue( o );
bool valid = TRUE;
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name != VCInternetProp && name != VCHomeProp &&
name != VCWorkProp &&
name != VCPreferredProp )
// ### preffered should map to default email
valid = FALSE;
}
if ( valid ) {
c.insertEmail( email );
}
}
else if ( name == VCURLProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectTypeInfo( o );
if ( name == VCHomeProp )
c.setHomeWebpage( value );
else if ( name == VCWorkProp )
c.setBusinessWebpage( value );
}
}
else if ( name == VCOrgProp ) {
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
if ( name == VCOrgNameProp )
c.setCompany( value );
else if ( name == VCOrgUnitProp )
c.setDepartment( value );
else if ( name == VCOrgUnit2Prop )
c.setOffice( value );
}
}
else if ( name == VCTitleProp ) {
c.setJobTitle( value );
}
else if ( name == "X-Qtopia-Profession" ) {
c.setProfession( value );
}
else if ( name == "X-Qtopia-Manager" ) {
c.setManager( value );
}
else if ( name == "X-Qtopia-Assistant" ) {
c.setAssistant( value );
}
else if ( name == "X-Qtopia-Spouse" ) {
c.setSpouse( value );
}
else if ( name == "X-Qtopia-Gender" ) {
c.setGender( value );
}
else if ( name == "X-Qtopia-Anniversary" ) {
c.setAnniversary( convVCardDateToDate( value ) );
}
else if ( name == "X-Qtopia-Nickname" ) {
c.setNickname( value );
}
else if ( name == "X-Qtopia-Children" ) {
c.setChildren( value );
}
else if ( name == VCBirthDateProp ) {
// Reading Birthdate regarding RFC 2425 (5.8.4)
c.setBirthday( convVCardDateToDate( value ) );
}
#if 0
else {
printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
VObjectIterator nit;
initPropIterator( &nit, o );
while( moreIteration( &nit ) ) {
VObject *o = nextVObject( &nit );
QCString name = vObjectName( o );
QString value = vObjectStringZValue( o );
printf(" subprop: %s = %s\n", name.data(), value.latin1() );
}
}
#endif
}
c.setFileAs();
return c;
}
VObject* OContactAccessBackend_VCard::createVObject( const OContact &c )
{
VObject *vcard = newVObject( VCCardProp );
safeAddPropValue( vcard, VCVersionProp, "2.1" );
safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
// full name
safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
// name properties
VObject *name = safeAddProp( vcard, VCNameProp );
safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
safeAddPropValue( name, VCGivenNameProp, c.firstName() );
safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp
index daf3506..e6a4787 100644
--- a/libopie2/opiepim/core/orecur.cpp
+++ b/libopie2/opiepim/core/orecur.cpp
@@ -1,451 +1,446 @@
#include <qshared.h>
#include <qtopia/timeconversion.h>
#include "orecur.h"
struct ORecur::Data : public QShared {
Data() : QShared() {
type = ORecur::NoRepeat;
freq = -1;
days = 0;
pos = 0;
- create = -1;
+ create = QDateTime::currentDateTime();
hasEnd = FALSE;
- end = 0;
+ end = QDate::currentDate();
}
char days; // Q_UINT8 for 8 seven days;)
ORecur::RepeatType type;
int freq;
int pos;
bool hasEnd : 1;
- time_t end;
- time_t create;
+ QDate end;
+ QDateTime create;
int rep;
QString app;
ExceptionList list;
QDate start;
};
ORecur::ORecur() {
data = new Data;
}
ORecur::ORecur( const ORecur& rec)
: data( rec.data )
{
data->ref();
}
ORecur::~ORecur() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
void ORecur::deref() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
bool ORecur::operator==( const ORecur& )const {
return false;
}
ORecur &ORecur::operator=( const ORecur& re) {
+ if ( *this == re ) return *this;
+
re.data->ref();
deref();
data = re.data;
return *this;
}
bool ORecur::doesRecur()const {
return !( type() == NoRepeat );
}
/*
* we try to be smart here
*
*/
bool ORecur::doesRecur( const QDate& date ) {
/* the day before the recurrance */
QDate da = date.addDays(-1);
QDate recur;
if (!nextOcurrence( da, recur ) )
return false;
return (recur == date);
}
// FIXME unuglify!
// GPL from Datebookdb.cpp
// FIXME exception list!
bool ORecur::nextOcurrence( const QDate& from, QDate& next ) {
// easy checks, first are we too far in the future or too far in the past?
QDate tmpDate;
int freq = frequency();
int diff, diff2, a;
int iday, imonth, iyear;
int dayOfWeek = 0;
int firstOfWeek = 0;
int weekOfMonth;
if (hasEndDate() && endDate() < from)
return FALSE;
if (start() >= from) {
next = start();
return TRUE;
}
switch ( type() ) {
case Weekly:
/* weekly is just daily by 7 */
/* first convert the repeatPattern.Days() mask to the next
day of week valid after from */
dayOfWeek = from.dayOfWeek();
dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
/* this is done in case freq > 1 and from in week not
for this round */
// firstOfWeek = 0; this is already done at decl.
while(!((1 << firstOfWeek) & days() ))
firstOfWeek++;
/* there is at least one 'day', or there would be no event */
while(!((1 << (dayOfWeek % 7)) & days() ))
dayOfWeek++;
dayOfWeek = dayOfWeek % 7; /* the actual day of week */
dayOfWeek -= start().dayOfWeek() -1;
firstOfWeek = firstOfWeek % 7; /* the actual first of week */
firstOfWeek -= start().dayOfWeek() -1;
// dayOfWeek may be negitive now
// day of week is number of days to add to start day
freq *= 7;
// FALL-THROUGH !!!!!
case Daily:
// the add is for the possible fall through from weekly */
if(start().addDays(dayOfWeek) > from) {
/* first week exception */
next = QDate(start().addDays(dayOfWeek) );
if ((next > endDate())
&& hasEndDate() )
return FALSE;
return TRUE;
}
/* if from is middle of a non-week */
diff = start().addDays(dayOfWeek).daysTo(from) % freq;
diff2 = start().addDays(firstOfWeek).daysTo(from) % freq;
if(diff != 0)
diff = freq - diff;
if(diff2 != 0)
diff2 = freq - diff2;
diff = QMIN(diff, diff2);
next = QDate(from.addDays(diff));
if ( (next > endDate())
&& hasEndDate() )
return FALSE;
return TRUE;
case MonthlyDay:
iday = from.day();
iyear = from.year();
imonth = from.month();
/* find equivelent day of month for this month */
dayOfWeek = start().dayOfWeek();
weekOfMonth = (start().day() - 1) / 7;
/* work out when the next valid month is */
a = from.year() - start().year();
a *= 12;
a = a + (imonth - start().month());
/* a is e.start()monthsFrom(from); */
if(a % freq) {
a = freq - (a % freq);
imonth = from.month() + a;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
}
/* imonth is now the first month after or on
from that matches the frequency given */
/* find for this month */
tmpDate = QDate( iyear, imonth, 1 );
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
while (iday > tmpDate.daysInMonth()) {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
tmpDate = QDate( iyear, imonth, 1 );
/* these loops could go for a while, check end case now */
if ((tmpDate > endDate()) && hasEndDate() )
return FALSE;
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
}
tmpDate = QDate(iyear, imonth, iday);
if (tmpDate >= from) {
next = tmpDate;
if ((next > endDate() ) && hasEndDate() )
return FALSE;
return TRUE;
}
/* need to find the next iteration */
do {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
tmpDate = QDate( iyear, imonth, 1 );
/* these loops could go for a while, check end case now */
if ((tmpDate > endDate()) && hasEndDate() )
return FALSE;
iday = 1;
iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
iday += 7 * weekOfMonth;
} while (iday > tmpDate.daysInMonth());
tmpDate = QDate(iyear, imonth, iday);
next = tmpDate;
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
case MonthlyDate:
iday = start().day();
iyear = from.year();
imonth = from.month();
a = from.year() - start().year();
a *= 12;
a = a + (imonth - start().month());
/* a is e.start()monthsFrom(from); */
if(a % freq) {
a = freq - (a % freq);
imonth = from.month() + a;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
}
/* imonth is now the first month after or on
from that matches the frequencey given */
/* this could go for a while, worse case, 4*12 iterations, probably */
while(!QDate::isValid(iyear, imonth, iday) ) {
imonth += freq;
if (imonth > 12) {
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
}
/* these loops could go for a while, check end case now */
if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
return FALSE;
}
if(QDate(iyear, imonth, iday) >= from) {
/* done */
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
}
/* ok, need to cycle */
imonth += freq;
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
while(!QDate::isValid(iyear, imonth, iday) ) {
imonth += freq;
imonth--;
iyear += imonth / 12;
imonth = imonth % 12;
imonth++;
if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
return FALSE;
}
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
case Yearly:
iday = start().day();
imonth = start().month();
iyear = from.year(); // after all, we want to start in this year
diff = 1;
if(imonth == 2 && iday > 28) {
/* leap year, and it counts, calculate actual frequency */
if(freq % 4)
if (freq % 2)
freq = freq * 4;
else
freq = freq * 2;
/* else divides by 4 already, leave freq alone */
diff = 4;
}
a = from.year() - start().year();
if(a % freq) {
a = freq - (a % freq);
iyear = iyear + a;
}
/* under the assumption we won't hit one of the special not-leap years twice */
if(!QDate::isValid(iyear, imonth, iday)) {
/* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
iyear += freq;
}
if(QDate(iyear, imonth, iday) >= from) {
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
}
/* iyear == from.year(), need to advance again */
iyear += freq;
/* under the assumption we won't hit one of the special not-leap years twice */
if(!QDate::isValid(iyear, imonth, iday)) {
/* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
iyear += freq;
}
next = QDate(iyear, imonth, iday);
if ((next > endDate()) && hasEndDate() )
return FALSE;
return TRUE;
default:
return FALSE;
}
}
ORecur::RepeatType ORecur::type()const{
return data->type;
}
int ORecur::frequency()const {
return data->freq;
}
int ORecur::position()const {
return data->pos;
}
char ORecur::days() const{
return data->days;
}
bool ORecur::hasEndDate()const {
return data->hasEnd;
}
QDate ORecur::endDate()const {
- return TimeConversion::fromUTC( data->end ).date();
+ return data->end;
}
QDate ORecur::start()const{
return data->start;
}
-time_t ORecur::endDateUTC()const {
- return data->end;
-}
-time_t ORecur::createTime()const {
+QDateTime ORecur::createdDateTime()const {
return data->create;
}
int ORecur::repetition()const {
return data->rep;
}
QString ORecur::service()const {
return data->app;
}
ORecur::ExceptionList& ORecur::exceptions() {
return data->list;
}
void ORecur::setType( const RepeatType& z) {
checkOrModify();
data->type = z;
}
void ORecur::setFrequency( int freq ) {
checkOrModify();
data->freq = freq;
}
void ORecur::setPosition( int pos ) {
checkOrModify();
data->pos = pos;
}
void ORecur::setDays( char c ) {
checkOrModify();
data->days = c;
}
void ORecur::setEndDate( const QDate& dt) {
checkOrModify();
- data->end = TimeConversion::toUTC( dt );
-}
-void ORecur::setEndDateUTC( time_t t) {
- checkOrModify();
- data->end = t;
+ data->end = dt;
}
-void ORecur::setCreateTime( time_t t) {
+void ORecur::setCreatedDateTime( const QDateTime& t) {
checkOrModify();
data->create = t;
}
void ORecur::setHasEndDate( bool b) {
checkOrModify();
data->hasEnd = b;
}
void ORecur::setRepitition( int rep ) {
checkOrModify();
data->rep = rep;
}
void ORecur::setService( const QString& app ) {
checkOrModify();
data->app = app;
}
void ORecur::setStart( const QDate& dt ) {
checkOrModify();
data->start = dt;
}
void ORecur::checkOrModify() {
if ( data->count != 1 ) {
data->deref();
Data* d2 = new Data;
d2->days = data->days;
d2->type = data->type;
d2->freq = data->freq;
d2->pos = data->pos;
d2->hasEnd = data->hasEnd;
d2->end = data->end;
d2->create = data->create;
d2->rep = data->rep;
d2->app = data->app;
d2->list = data->list;
d2->start = data->start;
data = d2;
}
}
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h
index 8713d97..1e0014b 100644
--- a/libopie2/opiepim/core/orecur.h
+++ b/libopie2/opiepim/core/orecur.h
@@ -1,83 +1,87 @@
/*
* GPL from TT
*/
#ifndef OPIE_RECUR_H
#define OPIE_RECUR_H
#include <sys/types.h>
#include <qdatetime.h>
#include <qvaluelist.h>
class ORecur {
public:
typedef QValueList<QDate> ExceptionList;
enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
MonthlyDate, Yearly };
enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
FRI = 0x10, SAT = 0x20, SUN = 0x40 };
ORecur();
ORecur( const ORecur& );
~ORecur();
ORecur &operator=( const ORecur& );
bool operator==(const ORecur& )const;
bool doesRecur()const;
/* if it recurrs on that day */
bool doesRecur( const QDate& );
RepeatType type()const;
int frequency()const;
int position()const;
char days()const;
bool hasEndDate()const;
QDate start()const;
QDate endDate()const;
- time_t endDateUTC()const;
- time_t createTime()const;
+ QDateTime createdDateTime()const;
+ /**
+ * starting on monday=0, sunday=6
+ * for convience
+ */
+ bool repeatOnWeekDay( int day )const;
/**
* FromWhereToStart is not included!!!
*/
bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate );
+
/**
* The module this ORecur belongs to
*/
QString service()const;
/*
* reference to the exception list
*/
ExceptionList &exceptions();
/**
* the current repetition
*/
int repetition()const;
void setType( const RepeatType& );
void setFrequency( int freq );
void setPosition( int pos );
void setDays( char c);
void setEndDate( const QDate& dt );
void setStart( const QDate& dt );
- void setEndDateUTC( time_t );
- void setCreateTime( time_t );
+ void setCreatedDateTime( const QDateTime& );
void setHasEndDate( bool b );
void setRepitition(int );
void setService( const QString& ser );
private:
void deref();
inline void checkOrModify();
class Data;
Data* data;
class ORecurPrivate;
ORecurPrivate *d;
};
#endif
diff --git a/libopie2/opiepim/core/otimezone.cpp b/libopie2/opiepim/core/otimezone.cpp
new file mode 100644
index 0000000..b2bd3aa
--- a/dev/null
+++ b/libopie2/opiepim/core/otimezone.cpp
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#include "otimezone.h"
+
+namespace {
+
+ QDateTime utcTime( time_t t) {
+ tm* broken = ::gmtime( &t );
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+ return ret;
+ }
+ QDateTime utcTime( time_t t, const QString& zone) {
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", zone.latin1(), true );
+ ::tzset();
+
+ tm* broken = ::localtime( &t );
+ ::setenv( "TZ", org, true );
+
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+
+ return ret;
+ }
+ time_t to_Time_t( const QDateTime& utc, const QString& str ) {
+ QDate d = utc.date();
+ QTime t = utc.time();
+
+ tm broken;
+ broken.tm_year = d.year() - 1900;
+ broken.tm_mon = d.month() - 1;
+ broken.tm_mday = d.day();
+ broken.tm_hour = t.hour();
+ broken.tm_min = t.minute();
+ broken.tm_sec = t.second();
+
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", str.latin1(), true );
+ ::tzset();
+
+ time_t ti = ::mktime( &broken );
+ ::setenv( "TZ", org, true );
+
+ return ti;
+ }
+}
+OTimeZone::OTimeZone( const ZoneName& zone )
+ : m_name(zone) {
+}
+OTimeZone::~OTimeZone() {
+}
+
+bool OTimeZone::isValid()const {
+ return !m_name.isEmpty();
+}
+
+/*
+ * we will get the current timezone
+ * and ask it to convert to the timezone date
+ */
+QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) {
+ return OTimeZone::current().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) {
+ return OTimeZone::utc().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::fromUTCDateTime( time_t t) {
+ return utcTime( t );
+}
+QDateTime OTimeZone::toDateTime( time_t t) {
+ return utcTime( t, m_name );
+}
+/*
+ * convert dt to utc using zone.m_name
+ * convert utc -> timeZoneDT using this->m_name
+ */
+QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) {
+ time_t utc = to_Time_t( dt, zone.m_name );
+ qWarning("%d %s", utc, zone.m_name.latin1() );
+ return utcTime( utc, m_name );
+}
+time_t OTimeZone::fromDateTime( const QDateTime& time ) {
+ return to_Time_t( time, m_name );
+}
+time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) {
+ return to_Time_t( time, "UTC" );
+}
+OTimeZone OTimeZone::current() {
+ QCString str = ::getenv("TZ");
+ OTimeZone zone( str );
+ return zone;
+}
+OTimeZone OTimeZone::utc() {
+ return OTimeZone("UTC");
+}
+QString OTimeZone::timeZone()const {
+ return m_name;
+}
diff --git a/libopie2/opiepim/core/otimezone.h b/libopie2/opiepim/core/otimezone.h
new file mode 100644
index 0000000..bb08349
--- a/dev/null
+++ b/libopie2/opiepim/core/otimezone.h
@@ -0,0 +1,71 @@
+#ifndef OPIE_TIME_ZONE_H
+#define OPIE_TIME_ZONE_H
+
+#include <time.h>
+#include <qdatetime.h>
+
+/**
+ * A very primitive class to convert time
+ * from one timezone to another
+ * and to localtime
+ * and time_t
+ */
+class OTimeZone {
+ public:
+ typedef QString ZoneName;
+ OTimeZone( const ZoneName& = ZoneName::null );
+ virtual ~OTimeZone(); // just in case.
+
+ bool isValid()const;
+
+ /**
+ * converts the QDateTime to a DateTime
+ * in the local timezone
+ * if QDateTime is 25th Jan and takes place in Europe/Berlin at 12h
+ * and the current timezone is Europe/London the returned
+ * time will be 11h.
+ */
+ QDateTime toLocalDateTime( const QDateTime& dt );
+
+ /**
+ * converts the QDateTime to UTC time
+ */
+ QDateTime toUTCDateTime( const QDateTime& dt );
+
+ /**
+ * reads the time_t into a QDateTime using UTC as timezone!
+ */
+ QDateTime fromUTCDateTime( time_t );
+
+ /**
+ * converts the time_t to the time in the timezone
+ */
+ QDateTime toDateTime( time_t );
+
+ /**
+ * converts the QDateTime from one timezone to this timeZone
+ */
+ QDateTime toDateTime( const QDateTime&, const OTimeZone& timeZone );
+
+ /**
+ * converts the date time into a time_t. It takes the timezone into account
+ */
+ time_t fromDateTime( const QDateTime& );
+
+ /**
+ * converts the datetime with timezone UTC
+ */
+ time_t fromUTCDateTime( const QDateTime& );
+
+ static OTimeZone current();
+ static OTimeZone utc();
+
+ QString timeZone()const;
+ private:
+ ZoneName m_name;
+ class Private;
+ Private* d;
+};
+
+
+#endif
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
new file mode 100644
index 0000000..71b9441
--- a/dev/null
+++ b/libopie2/opiepim/oevent.cpp
@@ -0,0 +1,427 @@
+#include <qshared.h>
+
+#include <qpe/palmtopuidgen.h>
+#include <qpe/categories.h>
+
+#include "orecur.h"
+#include "opimresolver.h"
+#include "opimnotifymanager.h"
+
+#include "oevent.h"
+
+namespace OCalendarHelper {
+ static int week( const QDate& date) {
+ // Calculates the week this date is in within that
+ // month. Equals the "row" is is in in the month view
+ int week = 1;
+ QDate tmp( date.year(), date.month(), 1 );
+ if ( date.dayOfWeek() < tmp.dayOfWeek() )
+ ++week;
+
+ week += ( date.day() - 1 ) / 7;
+
+ return week;
+ }
+ static int occurence( const QDate& date) {
+ // calculates the number of occurrances of this day of the
+ // week till the given date (e.g 3rd Wednesday of the month)
+ return ( date.day() - 1 ) / 7 + 1;
+ }
+ static int dayOfWeek( char day ) {
+ int dayOfWeek = 1;
+ char i = ORecur::MON;
+ while ( !( i & day ) && i <= ORecur::SUN ) {
+ i <<= 1;
+ ++dayOfWeek;
+ }
+ return dayOfWeek;
+ }
+ static int monthDiff( const QDate& first, const QDate& second ) {
+ return ( second.year() - first.year() ) * 12 +
+ second.month() - first.month();
+ }
+}
+
+struct OEvent::Data : public QShared {
+ Data() : QShared() {
+ recur = 0;
+ manager = 0;
+ isAllDay = false;
+ }
+ ~Data() {
+ delete manager;
+ delete recur;
+ }
+ QString description;
+ QString location;
+ OPimNotifyManager* manager;
+ ORecur* recur;
+ QString note;
+ QDateTime created;
+ QDateTime start;
+ QDateTime end;
+ bool isAllDay : 1;
+ QString timezone;
+};
+
+OEvent::OEvent( int uid )
+ : OPimRecord( uid ) {
+ data = new Data;
+}
+OEvent::OEvent( const OEvent& ev)
+ : OPimRecord( ev ), data( ev.data )
+{
+ data->ref();
+}
+OEvent::~OEvent() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+OEvent& OEvent::operator=( const OEvent& ev) {
+ if ( *this == ev ) return *this;
+
+ OPimRecord::operator=( ev );
+ ev.data->ref();
+ deref();
+ data = ev.data;
+
+
+ return *this;
+}
+QString OEvent::description()const {
+ return data->description;
+}
+void OEvent::setDescription( const QString& description ) {
+ changeOrModify();
+ data->description = description;
+}
+void OEvent::setLocation( const QString& loc ) {
+ changeOrModify();
+ data->location = loc;
+}
+QString OEvent::location()const {
+ return data->location;
+}
+OPimNotifyManager &OEvent::notifiers() {
+ // I hope we can skip the changeOrModify here
+ // the notifier should take care of it
+ // and OPimNotify is shared too
+ if (!data->manager )
+ data->manager = new OPimNotifyManager;
+
+ return *data->manager;
+}
+bool OEvent::hasNotifiers()const {
+ return ( data->manager);
+}
+ORecur OEvent::recurrence()const {
+ if (!data->recur)
+ data->recur = new ORecur;
+
+ return *data->recur;
+}
+void OEvent::setRecurrence( const ORecur& rec) {
+ changeOrModify();
+ if (data->recur )
+ (*data->recur) = rec;
+ else
+ data->recur = new ORecur( rec );
+}
+bool OEvent::hasRecurrence()const {
+ return data->recur;
+}
+QString OEvent::note()const {
+ return data->note;
+}
+void OEvent::setNote( const QString& note ) {
+ changeOrModify();
+ data->note = note;
+}
+QDateTime OEvent::createdDateTime()const {
+ return data->created;
+}
+void OEvent::setCreatedDateTime( const QDateTime& time ) {
+ changeOrModify();
+ data->created = time;
+}
+QDateTime OEvent::startDateTime()const {
+ if ( data->isAllDay )
+ return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
+ return data->start;
+}
+QDateTime OEvent::startDateTimeInZone()const {
+ /* if no timezone, or all day event or if the current and this timeZone match... */
+ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
+
+ OTimeZone zone(data->timezone );
+ return zone.toDateTime( data->start, OTimeZone::current() );
+}
+void OEvent::setStartDateTime( const QDateTime& dt ) {
+ changeOrModify();
+ data->start = dt;
+}
+QDateTime OEvent::endDateTime()const {
+ /*
+ * if all Day event the end time needs
+ * to be on the same day as the start
+ */
+ if ( data->isAllDay )
+ return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
+ return data->end;
+}
+QDateTime OEvent::endDateTimeInZone()const {
+ /* if no timezone, or all day event or if the current and this timeZone match... */
+ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
+
+ OTimeZone zone(data->timezone );
+ return zone.toDateTime( data->end, OTimeZone::current() );
+}
+void OEvent::setEndDateTime( const QDateTime& dt ) {
+ changeOrModify();
+ data->end = dt;
+}
+bool OEvent::isMultipleDay()const {
+ return data->end.date().day() - data->start.date().day();
+}
+bool OEvent::isAllDay()const {
+ return data->isAllDay;
+}
+void OEvent::setTimeZone( const QString& tz ) {
+ changeOrModify();
+ data->timezone = tz;
+}
+QString OEvent::timeZone()const {
+ return data->timezone;
+}
+bool OEvent::match( const QRegExp& )const {
+ // FIXME
+ return false;
+}
+QString OEvent::toRichText()const {
+ // FIXME
+ return "OEvent test";
+}
+QString OEvent::toShortText()const {
+ return "OEvent shotText";
+}
+QString OEvent::type()const {
+ return QString::fromLatin1("OEvent");
+}
+QString OEvent::recordField( int /*id */ )const {
+ return QString::null;
+}
+int OEvent::rtti() {
+ return OPimResolver::DateBook;
+}
+bool OEvent::loadFromStream( QDataStream& ) {
+ return true;
+}
+bool OEvent::saveToStream( QDataStream& )const {
+ return true;
+}
+void OEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->description = data->description;
+ d2->location = data->location;
+ d2->manager = data->manager;
+ d2->recur = data->recur;
+ d2->note = data->note;
+ d2->created = data->created;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->isAllDay = data->isAllDay;
+ d2->timezone = data->timezone;
+
+ data = d2;
+ }
+}
+void OEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+// FIXME
+QMap<int, QString> OEvent::toMap()const {
+ return QMap<int, QString>();
+}
+QMap<QString, QString> OEvent::toExtraMap()const {
+ return QMap<QString, QString>();
+}
+
+
+struct OEffectiveEvent::Data : public QShared {
+ Data() : QShared() {
+ }
+ OEvent event;
+ QDate date;
+ QTime start, end;
+ QDate startDate, endDate;
+ bool dates : 1;
+};
+
+OEffectiveEvent::OEffectiveEvent() {
+ data = new Data;
+ data->date = QDate::currentDate();
+ data->start = data->end = QTime::currentTime();
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
+ Position pos ) {
+ data = new Data;
+ data->event = ev;
+ data->date = startDate;
+ if ( pos & Start )
+ data->start = ev.startDateTime().time();
+ else
+ data->start = QTime( 0, 0, 0 );
+
+ if ( pos & End )
+ data->end = ev.endDateTime().time();
+ else
+ data->end = QTime( 23, 59, 59 );
+
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
+ data = ev.data;
+ data->ref();
+}
+OEffectiveEvent::~OEffectiveEvent() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
+ if ( *this == ev ) return *this;
+
+ ev.data->ref();
+ deref();
+ data = ev.data;
+
+ return *this;
+}
+
+void OEffectiveEvent::setStartTime( const QTime& ti) {
+ changeOrModify();
+ data->start = ti;
+}
+void OEffectiveEvent::setEndTime( const QTime& en) {
+ changeOrModify();
+ data->end = en;
+}
+void OEffectiveEvent::setEvent( const OEvent& ev) {
+ changeOrModify();
+ data->event = ev;
+}
+void OEffectiveEvent::setDate( const QDate& da) {
+ changeOrModify();
+ data->date = da;
+}
+void OEffectiveEvent::setEffectiveDates( const QDate& from,
+ const QDate& to ) {
+ if (!from.isValid() ) {
+ data->dates = false;
+ return;
+ }
+
+ data->startDate = from;
+ data->endDate = to;
+}
+QString OEffectiveEvent::description()const {
+ return data->event.description();
+}
+QString OEffectiveEvent::location()const {
+ return data->event.location();
+}
+QString OEffectiveEvent::note()const {
+ return data->event.note();
+}
+OEvent OEffectiveEvent::event()const {
+ return data->event;
+}
+QTime OEffectiveEvent::startTime()const {
+ return data->start;
+}
+QTime OEffectiveEvent::endTime()const {
+ return data->end;
+}
+QDate OEffectiveEvent::date()const {
+ return data->date;
+}
+int OEffectiveEvent::length()const {
+ return (data->end.hour() * 60 - data->start.hour() * 60)
+ + QABS(data->start.minute() - data->end.minute() );
+}
+int OEffectiveEvent::size()const {
+ return ( data->end.hour() - data->start.hour() ) * 3600
+ + (data->end.minute() - data->start.minute() * 60
+ + data->end.second() - data->start.second() );
+}
+QDate OEffectiveEvent::startDate()const {
+ if ( data->dates )
+ return data->startDate;
+ else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
+ return data->date;
+ else
+ return data->event.startDateTime().date();
+}
+QDate OEffectiveEvent::endDate()const {
+ if ( data->dates )
+ return data->endDate;
+ else if ( data->event.hasRecurrence() )
+ return data->date;
+ else
+ return data->event.endDateTime().date();
+}
+void OEffectiveEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+void OEffectiveEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->event = data->event;
+ d2->date = data->date;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->startDate = data->startDate;
+ d2->endDate = data->endDate;
+ d2->dates = data->dates;
+ data = d2;
+ }
+}
+bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{
+ if ( data->date < e.date() )
+ return TRUE;
+ if ( data->date == e.date() )
+ return ( startTime() < e.startTime() );
+ else
+ return FALSE;
+}
+bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{
+ return (data->date <= e.date() );
+}
+bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const {
+ return ( date() == e.date()
+ && startTime() == e.startTime()
+ && endTime()== e.endTime()
+ && event() == e.event() );
+}
+bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const {
+ return !(*this == e );
+}
+bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const {
+ return !(*this <= e );
+}
+bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const {
+ return !(*this < e);
+}
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h
new file mode 100644
index 0000000..4489be7
--- a/dev/null
+++ b/libopie2/opiepim/oevent.h
@@ -0,0 +1,198 @@
+// CONTAINS GPLed code of TT
+
+#ifndef OPIE_PIM_EVENT_H
+#define OPIE_PIM_EVENT_H
+
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qvaluelist.h>
+
+#include <qpe/recordfields.h>
+#include <qpe/palmtopuidgen.h>
+
+#include "otimezone.h"
+#include "opimrecord.h"
+
+namespace OCalendarHelper {
+ /** calculate the week number of the date */
+ static int week( const QDate& );
+ /** calculate the occurence of week days since the start of the month */
+ static int ocurrence( const QDate& );
+
+ // returns the dayOfWeek for the *first* day it finds (ignores
+ // any further days!). Returns 1 (Monday) if there isn't any day found
+ static int dayOfWeek( char day );
+
+ /** returns the diff of month */
+ static int monthDiff( const QDate& first, const QDate& second );
+
+}
+
+class OPimNotifyManager;
+class ORecur;
+class OEvent : public OPimRecord {
+public:
+ typedef QValueList<OEvent> ValueList;
+ enum RecordFields {
+ Uid = Qtopia::UID_ID,
+ Category = Qtopia::CATEGORY_ID,
+ Description,
+ Location,
+ Alarm,
+ Reminder,
+ Recurrence,
+ Note,
+ Created,
+ StartDate,
+ EndDate,
+ AllDay,
+ TimeZone
+ };
+
+ OEvent(int uid = 0);
+ OEvent( const OEvent& );
+ ~OEvent();
+ OEvent &operator=( const OEvent& );
+
+ QString description()const;
+ void setDescription( const QString& description );
+
+ QString location()const;
+ void setLocation( const QString& loc );
+
+ bool hasNotifiers()const;
+ OPimNotifyManager &notifiers();
+
+ ORecur recurrence()const;
+ void setRecurrence( const ORecur& );
+ bool hasRecurrence()const;
+
+ QString note()const;
+ void setNote( const QString& note );
+
+
+ QDateTime createdDateTime()const;
+ void setCreatedDateTime( const QDateTime& dt);
+
+ /** set the date to dt. dt is the QDateTime in localtime */
+ void setStartDateTime( const QDateTime& );
+ /** returns the datetime in the local timeZone */
+ QDateTime startDateTime()const;
+
+ /** returns the start datetime in the current zone */
+ QDateTime startDateTimeInZone()const;
+
+ /** in current timezone */
+ void setEndDateTime( const QDateTime& );
+ /** in current timezone */
+ QDateTime endDateTime()const;
+ QDateTime endDateTimeInZone()const;
+
+ bool isMultipleDay()const;
+ bool isAllDay()const;
+ void setAllDay( bool isAllDay );
+
+ /* pin this event to a timezone! FIXME */
+ void setTimeZone( const QString& timeZone );
+ QString timeZone()const;
+
+
+ bool match( const QRegExp& )const;
+
+
+
+
+ /* needed reimp */
+ QString toRichText()const;
+ QString toShortText()const;
+ QString type()const;
+
+ QMap<int, QString> toMap()const;
+ QMap<QString, QString> toExtraMap()const;
+ QString recordField(int )const;
+
+ static int rtti();
+
+ bool loadFromStream( QDataStream& );
+ bool saveToStream( QDataStream& )const;
+
+/* bool operator==( const OEvent& );
+ bool operator!=( const OEvent& );
+ bool operator<( const OEvent& );
+ bool operator<=( const OEvent& );
+ bool operator>( const OEvent& );
+ bool operator>=(const OEvent& );
+*/
+private:
+ inline void changeOrModify();
+ void deref();
+ struct Data;
+ Data* data;
+ class Private;
+ Private* priv;
+
+};
+
+/**
+ * AN Event can span through multiple days. We split up a multiday eve
+ */
+
+class OEffectiveEvent {
+public:
+ QValueList<OEffectiveEvent> ValueList;
+ enum Position { MidWay, Start, End, StartEnd };
+ // If we calculate the effective event of a multi-day event
+ // we have to figure out whether we are at the first day,
+ // at the end, or anywhere else ("middle"). This is important
+ // for the start/end times (00:00/23:59)
+ // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi-
+ // day event
+ // Start: start time -> 23:59
+ // End: 00:00 -> end time
+ // Start | End == StartEnd: for single-day events (default)
+ // here we draw start time -> end time
+ OEffectiveEvent();
+ OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd );
+ OEffectiveEvent( const OEffectiveEvent& );
+ OEffectiveEvent &operator=(const OEffectiveEvent& );
+ ~OEffectiveEvent();
+
+ void setStartTime( const QTime& );
+ void setEndTime( const QTime& );
+ void setEvent( const OEvent& );
+ void setDate( const QDate& );
+
+ void setEffectiveDates( const QDate& from, const QDate& to );
+
+ QString description()const;
+ QString location()const;
+ QString note()const;
+ OEvent event()const;
+ QTime startTime()const;
+ QTime endTime()const;
+ QDate date()const;
+
+ /* return the length in hours */
+ int length()const;
+ int size()const;
+
+ QDate startDate()const;
+ QDate endDate()const;
+
+ bool operator<( const OEffectiveEvent &e ) const;
+ bool operator<=( const OEffectiveEvent &e ) const;
+ bool operator==( const OEffectiveEvent &e ) const;
+ bool operator!=( const OEffectiveEvent &e ) const;
+ bool operator>( const OEffectiveEvent &e ) const;
+ bool operator>= ( const OEffectiveEvent &e ) const;
+
+private:
+ void deref();
+ inline void changeOrModify();
+ class Private;
+ Private* priv;
+ struct Data;
+ Data* data;
+
+};
+#endif
diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp
index b4d4aa9..049359e 100644
--- a/libopie2/opiepim/otodo.cpp
+++ b/libopie2/opiepim/otodo.cpp
@@ -1,422 +1,424 @@
#include <qobject.h>
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/stringutil.h>
#include <qpe/palmtoprecord.h>
#include <qpe/stringutil.h>
#include <qpe/categories.h>
#include <qpe/categoryselect.h>
#include "opimstate.h"
#include "orecur.h"
#include "opimmaintainer.h"
#include "opimnotifymanager.h"
#include "opimresolver.h"
#include "otodo.h"
struct OTodo::OTodoData : public QShared {
OTodoData() : QShared() {
};
QDate date;
bool isCompleted:1;
bool hasDate:1;
int priority;
QString desc;
QString sum;
QMap<QString, QString> extra;
ushort prog;
OPimState state;
ORecur recur;
OPimMaintainer maintainer;
QDate start;
QDate completed;
OPimNotifyManager notifiers;
};
OTodo::OTodo(const OTodo &event )
: OPimRecord( event ), data( event.data )
{
data->ref();
// qWarning("ref up");
}
OTodo::~OTodo() {
// qWarning("~OTodo " );
if ( data->deref() ) {
// qWarning("OTodo::dereffing");
delete data;
data = 0l;
}
}
OTodo::OTodo(bool completed, int priority,
const QArray<int> &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData " + summary);
setCategories( category );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
}
OTodo::OTodo(bool completed, int priority,
const QStringList &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData" + summary);
setCategories( idsFromString( category.join(";") ) );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
}
bool OTodo::match( const QRegExp &regExp )const
{
if( QString::number( data->priority ).find( regExp ) != -1 ){
return true;
}else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
return true;
}else if(data->desc.find( regExp ) != -1 ){
return true;
}else if(data->sum.find( regExp ) != -1 ) {
return true;
}
return false;
}
bool OTodo::isCompleted() const
{
return data->isCompleted;
}
bool OTodo::hasDueDate() const
{
return data->hasDate;
}
bool OTodo::hasStartDate()const {
return data->start.isValid();
}
bool OTodo::hasCompletedDate()const {
return data->completed.isValid();
}
int OTodo::priority()const
{
return data->priority;
}
QString OTodo::summary() const
{
return data->sum;
}
ushort OTodo::progress() const
{
return data->prog;
}
QDate OTodo::dueDate()const
{
return data->date;
}
QDate OTodo::startDate()const {
return data->start;
}
QDate OTodo::completedDate()const {
return data->completed;
}
QString OTodo::description()const
{
return data->desc;
}
OPimState OTodo::state()const {
return data->state;
}
ORecur OTodo::recurrence()const {
return data->recur;
}
OPimMaintainer OTodo::maintainer()const {
return data->maintainer;
}
void OTodo::setCompleted( bool completed )
{
changeOrModify();
data->isCompleted = completed;
}
void OTodo::setHasDueDate( bool hasDate )
{
changeOrModify();
data->hasDate = hasDate;
}
void OTodo::setDescription(const QString &desc )
{
// qWarning( "desc " + desc );
changeOrModify();
data->desc = Qtopia::simplifyMultiLineSpace(desc );
}
void OTodo::setSummary( const QString& sum )
{
changeOrModify();
data->sum = sum;
}
void OTodo::setPriority(int prio )
{
changeOrModify();
data->priority = prio;
}
void OTodo::setDueDate( const QDate& date )
{
changeOrModify();
data->date = date;
}
void OTodo::setStartDate( const QDate& date ) {
changeOrModify();
data->start = date;
}
void OTodo::setCompletedDate( const QDate& date ) {
changeOrModify();
data->completed = date;
}
void OTodo::setState( const OPimState& state ) {
changeOrModify();
data->state = state;
}
void OTodo::setRecurrence( const ORecur& rec) {
changeOrModify();
data->recur = rec;
}
void OTodo::setMaintainer( const OPimMaintainer& pim ) {
changeOrModify();
data->maintainer = pim;
}
bool OTodo::isOverdue( )
{
if( data->hasDate && !data->isCompleted)
return QDate::currentDate() > data->date;
return false;
}
void OTodo::setProgress(ushort progress )
{
changeOrModify();
data->prog = progress;
}
QString OTodo::toShortText() const {
return summary();
}
/*!
Returns a richt text string
*/
QString OTodo::toRichText() const
{
QString text;
QStringList catlist;
// Description of the todo
if ( !summary().isEmpty() ) {
text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
}
if( !description().isEmpty() ){
text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
}
text += "<br><br><br>";
text += "<b>" + QObject::tr( "Priority:") +" </b>"
+ QString::number( priority() ) + " <br>";
text += "<b>" + QObject::tr( "Progress:") + " </b>"
+ QString::number( progress() ) + " %<br>";
if (hasDueDate() ){
text += "<b>" + QObject::tr( "Deadline:") + " </b>";
text += dueDate().toString();
text += "<br>";
}
text += "<b>" + QObject::tr( "Category:") + "</b> ";
text += categoryNames( "Todo List" ).join(", ");
text += "<br>";
return text;
}
OPimNotifyManager& OTodo::notifiers() {
return data->notifiers;
}
bool OTodo::operator<( const OTodo &toDoEvent )const{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() < toDoEvent.priority();
}else{
return dueDate() < toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator<=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() <= toDoEvent.priority();
}else{
return dueDate() <= toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator>(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator>=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator==(const OTodo &toDoEvent )const
{
if ( data->priority != toDoEvent.data->priority ) return false;
if ( data->priority != toDoEvent.data->prog ) return false;
if ( data->isCompleted != toDoEvent.data->isCompleted ) return false;
if ( data->hasDate != toDoEvent.data->hasDate ) return false;
if ( data->date != toDoEvent.data->date ) return false;
if ( data->sum != toDoEvent.data->sum ) return false;
if ( data->desc != toDoEvent.data->desc ) return false;
if ( data->maintainer != toDoEvent.data->maintainer )
return false;
return OPimRecord::operator==( toDoEvent );
}
void OTodo::deref() {
// qWarning("deref in ToDoEvent");
if ( data->deref() ) {
// qWarning("deleting");
delete data;
data= 0;
}
}
OTodo &OTodo::operator=(const OTodo &item )
{
+ if ( *this == item ) return *this;
+
OPimRecord::operator=( item );
//qWarning("operator= ref ");
item.data->ref();
deref();
data = item.data;
return *this;
}
QMap<int, QString> OTodo::toMap() const {
QMap<int, QString> map;
map.insert( Uid, QString::number( uid() ) );
map.insert( Category, idsToString( categories() ) );
map.insert( HasDate, QString::number( data->hasDate ) );
map.insert( Completed, QString::number( data->isCompleted ) );
map.insert( Description, data->desc );
map.insert( Summary, data->sum );
map.insert( Priority, QString::number( data->priority ) );
map.insert( DateDay, QString::number( data->date.day() ) );
map.insert( DateMonth, QString::number( data->date.month() ) );
map.insert( DateYear, QString::number( data->date.year() ) );
map.insert( Progress, QString::number( data->prog ) );
// map.insert( CrossReference, crossToString() );
/* FIXME!!! map.insert( State, );
map.insert( Recurrence, );
map.insert( Reminders, );
map.
*/
return map;
}
QMap<QString, QString> OTodo::toExtraMap()const {
return data->extra;
}
/**
* change or modify looks at the ref count and either
* creates a new QShared Object or it can modify it
* right in place
*/
void OTodo::changeOrModify() {
if ( data->count != 1 ) {
qWarning("changeOrModify");
data->deref();
OTodoData* d2 = new OTodoData();
copy(data, d2 );
data = d2;
}
}
// WATCHOUT
/*
* if you add something to the Data struct
* be sure to copy it here
*/
void OTodo::copy( OTodoData* src, OTodoData* dest ) {
dest->date = src->date;
dest->isCompleted = src->isCompleted;
dest->hasDate = src->hasDate;
dest->priority = src->priority;
dest->desc = src->desc;
dest->sum = src->sum;
dest->extra = src->extra;
dest->prog = src->prog;
dest->state = src->state;
dest->recur = src->recur;
dest->maintainer = src->maintainer;
dest->start = src->start;
dest->completed = src->completed;
dest->notifiers = src->notifiers;
}
QString OTodo::type() const {
return QString::fromLatin1("OTodo");
}
QString OTodo::recordField(int /*id*/ )const {
return QString::null;
}
int OTodo::rtti(){
return OPimResolver::TodoList;
}