-rw-r--r-- | libopie/orecurrancebase.ui | 713 | ||||
-rw-r--r-- | libopie/orecurrancewidget.cpp | 556 | ||||
-rw-r--r-- | libopie/orecurrancewidget.h | 68 | ||||
-rw-r--r-- | libopie/pim/libopie.pro | 6 | ||||
-rw-r--r-- | libopie/pim/orecordlist.h | 2 | ||||
-rw-r--r-- | libopie/pim/orecur.cpp | 127 | ||||
-rw-r--r-- | libopie/pim/orecur.h | 54 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 2 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccesssql.cpp | 2 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.cpp | 127 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.h | 54 | ||||
-rw-r--r-- | libopie2/opiepim/orecordlist.h | 2 |
12 files changed, 1709 insertions, 4 deletions
diff --git a/libopie/orecurrancebase.ui b/libopie/orecurrancebase.ui new file mode 100644 index 0000000..baf79d3 --- a/dev/null +++ b/libopie/orecurrancebase.ui @@ -0,0 +1,713 @@ +<!DOCTYPE UI><UI> +<class>ORecurranceBase</class> +<comment>********************************************************************* +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** $Id$ +** +*********************************************************************</comment> +<widget> + <class>QDialog</class> + <property stdset="1"> + <name>name</name> + <cstring>ORecurranceBase</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>246</width> + <height>309</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Repeating Event </string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>5</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>1</number> + </property> + <widget> + <class>QButtonGroup</class> + <property stdset="1"> + <name>name</name> + <cstring>fraType</cstring> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>NoFrame</enum> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>Sunken</enum> + </property> + <property stdset="1"> + <name>title</name> + <string></string> + </property> + <property stdset="1"> + <name>exclusive</name> + <bool>true</bool> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>5</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>1</number> + </property> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdNone</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>None</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdDay</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Day</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdWeek</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Week</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdMonth</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Month</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdYear</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Year</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout4</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblEvery</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Every:</string> + </property> + </widget> + <widget> + <class>QSpinBox</class> + <property stdset="1"> + <name>name</name> + <cstring>spinFreq</cstring> + </property> + <property stdset="1"> + <name>minValue</name> + <number>1</number> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblFreq</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Frequency</string> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout8</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblEnd</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>End On:</string> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdEnd</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>No End Date</string> + </property> + </widget> + <widget> + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>chkNoEnd</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>No End Date</string> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QButtonGroup</class> + <property stdset="1"> + <name>name</name> + <cstring>fraExtra</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>Box</enum> + </property> + <property stdset="1"> + <name>title</name> + <string>Repeat On</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>5</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>1</number> + </property> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra1</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Mon</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra2</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Tue</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra3</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Wed</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra4</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Thu</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra5</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Fri</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra6</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Sat</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QToolButton</class> + <property stdset="1"> + <name>name</name> + <cstring>cmdExtra7</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Sun</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QFrame</class> + <property stdset="1"> + <name>name</name> + <cstring>Frame3</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>Box</enum> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>Sunken</enum> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>5</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>1</number> + </property> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout6</cstring> + </property> + <property> + <name>layoutSpacing</name> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>0</number> + </property> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblRepeat</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>3</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Every</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignTop|AlignLeft</set> + </property> + <property> + <name>hAlign</name> + </property> + <property> + <name>vAlign</name> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblVar1</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Var1</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignTop|AlignLeft</set> + </property> + <property> + <name>hAlign</name> + </property> + <property> + <name>vAlign</name> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblVar2</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Var 2</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignTop|AlignRight</set> + </property> + <property> + <name>hAlign</name> + </property> + <property> + <name>vAlign</name> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblWeekVar</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>WeekVar</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignTop|AlignHCenter</set> + </property> + <property> + <name>hAlign</name> + </property> + <property> + <name>vAlign</name> + </property> + </widget> + </vbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>chkNoEnd</sender> + <signal>toggled(bool)</signal> + <receiver>cmdEnd</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>chkNoEnd</sender> + <signal>toggled(bool)</signal> + <receiver>ORecurranceBase</receiver> + <slot>slotNoEnd(bool)</slot> + </connection> + <connection> + <sender>spinFreq</sender> + <signal>valueChanged(int)</signal> + <receiver>lblVar1</receiver> + <slot>setNum(int)</slot> + </connection> + <connection> + <sender>spinFreq</sender> + <signal>valueChanged(int)</signal> + <receiver>ORecurranceBase</receiver> + <slot>setupRepeatLabel( int )</slot> + </connection> + <connection> + <sender>fraType</sender> + <signal>clicked(int)</signal> + <receiver>ORecurranceBase</receiver> + <slot>slotSetRType( int )</slot> + </connection> + <connection> + <sender>fraExtra</sender> + <signal>clicked(int)</signal> + <receiver>ORecurranceBase</receiver> + <slot>slotMonthLabel( int )</slot> + </connection> + <connection> + <sender>fraExtra</sender> + <signal>clicked(int)</signal> + <receiver>ORecurranceBase</receiver> + <slot>slotWeekLabel()</slot> + </connection> + <slot access="public">setupRepeatLabel( const QString & )</slot> + <slot access="public">setupRepeatLabel( int )</slot> + <slot access="public">slotMonthLabel( int )</slot> + <slot access="public">slotNoEnd(bool)</slot> + <slot access="public">slotSetRType( int )</slot> + <slot access="public">slotWeekLabel()</slot> +</connections> +</UI> diff --git a/libopie/orecurrancewidget.cpp b/libopie/orecurrancewidget.cpp new file mode 100644 index 0000000..53cee65 --- a/dev/null +++ b/libopie/orecurrancewidget.cpp @@ -0,0 +1,556 @@ +#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(); + 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 ) ); +} +ORecurranceWidget::~ORecurranceWidget() { + +} +ORecur ORecurranceWidget::recurrance()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 ) ); + 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" ); + break; + } + return str; +} diff --git a/libopie/orecurrancewidget.h b/libopie/orecurrancewidget.h new file mode 100644 index 0000000..f2d7f87 --- a/dev/null +++ b/libopie/orecurrancewidget.h @@ -0,0 +1,68 @@ +/* + * GPL and based on the widget from TT + */ + +#ifndef OPIE_RECURRANCE_WIDGET_H +#define OPIE_RECURRANCE_WIDGET_H + +#include <qlist.h> +#include <qtoolbutton.h> +#include <qcheckbox.h> +#include <qdatetime.h> +#include <qbuttongroup.h> + +#include <qpe/datebookmonth.h> + +#include "orecurrancebase.h" +#include <opie/orecur.h> + +class ORecurranceWidget : public ORecurranceBase { + Q_OBJECT +public: + ORecurranceWidget( bool startOnMonday, + const QDate& start, QWidget* parent = 0, + const char* name = 0, bool modal = TRUE, + WFlags fl = 0 ); + ORecurranceWidget( bool startOnMonday, + const ORecur& rp, const QDate& start, + QWidget* parent = 0, const char* name =0, + bool modal = TRUE, WFlags = 0 ); + ~ORecurranceWidget(); + ORecur recurrance()const; + QDate endDate()const; + +public slots: + void slotSetRType( int ); + void endDateChanged( int, int, int ); + void slotNoEnd( bool unused ); + +private slots: + void setupRepeatLabel( const QString& ); + void setupRepeatLabel( int ); + void slotWeekLabel(); + void slotMonthLabel( int ); + void slotChangeStartOfWeek( bool onMonday ); + +private: + void setupNone(); + void setupDaily(); + void setupWeekly(); + void setupMonthly(); + void setupYearly(); + + enum repeatButtons { None, Day, Week, Month, Year }; + void init(); + void hideExtras(); + void showRepeatStuff(); + + QList<QToolButton> listRTypeButtons; + QList<QToolButton> listExtra; + QDate start; // only used in one spot... + QDate end; + repeatButtons currInterval; + bool startWeekOnMonday : 1; + DateBookMonth *repeatPicker; + +}; + +#endif diff --git a/libopie/pim/libopie.pro b/libopie/pim/libopie.pro index 1dacbe7..b871374 100644 --- a/libopie/pim/libopie.pro +++ b/libopie/pim/libopie.pro @@ -1,75 +1,77 @@ TEMPLATE = lib CONFIG += qte warn_on release HEADERS = ofontmenu.h \ tododb.h \ todoevent.h todoresource.h \ todovcalresource.h xmltree.h \ colordialog.h colorpopupmenu.h \ oclickablelabel.h oprocctrl.h \ oprocess.h odevice.h \ otimepicker.h otabwidget.h \ otabbar.h otabinfo.h \ ofileselector/ofiledialog.h \ ofileselector/ofilelistview.h \ ofileselector/ofileselector.h \ ofileselector/ofileselectoritem.h \ ofileselector/ofileview.h \ ofileselector/olister.h \ ofileselector/olocallister.h \ ofileselector/ofileselectormain.h \ pim/opimrecord.h \ pim/otodo.h \ pim/orecordlist.h \ pim/opimaccesstemplate.h \ pim/opimaccessbackend.h \ pim/otodoaccess.h \ pim/otodacessbackend.h \ pim/ocontact.h \ pim/ocontactaccess.h \ pim/ocontactaccessbackend.h \ - pim/ocontactaccessbackend_xml.h + pim/ocontactaccessbackend_xml.h \ + pim/orecord.h SOURCES = ofontmenu.cc \ xmltree.cc \ tododb.cpp todoevent.cpp \ todovcalresource.cpp colordialog.cpp \ colorpopupmenu.cpp oclickablelabel.cpp \ oprocctrl.cpp oprocess.cpp \ odevice.cpp otimepicker.cpp \ otabwidget.cpp otabbar.cpp \ ofileselector/ofiledialog.cpp \ ofileselector/ofilelistview.cpp \ ofileselector/ofileselector.cpp \ ofileselector/ofileselectoritem.cpp \ ofileselector/ofileview.cpp \ ofileselector/olister.cpp \ ofileselector/olocallister.cpp \ ofileselector/ofileselectormain.cpp \ pim/otodo.cpp \ pim/opimrecord.cpp \ pim/otodoaccess.cpp \ pim/otodoaccessbackend.cpp \ pim/ocontact.cpp \ - pim/ocontactaccess.cpp + pim/ocontactaccess.cpp \ + pim/orecord.cpp TARGET = opie INCLUDEPATH += $(OPIEDIR)/include DESTDIR = $(QTDIR)/lib$(PROJMAK) #VERSION = 1.0.0 INTERFACES = otimepickerbase.ui TRANSLATIONS = ../i18n/de/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 diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h index 5404910..e377447 100644 --- a/libopie/pim/orecordlist.h +++ b/libopie/pim/orecordlist.h @@ -71,200 +71,202 @@ private: bool m_direction :1; /* d pointer for future versions */ class IteratorPrivate; IteratorPrivate *d; }; /** * The recordlist used as a return type * from OPimAccessTemplate */ template <class T = OPimRecord > class ORecordList { public: typedef OTemplateBase<T> Base; typedef ORecordListIterator<T> Iterator; /** * c'tor */ ORecordList () { } ORecordList( const QArray<int>& ids, const Base* ); ~ORecordList(); /** * the first iterator */ Iterator begin(); /** * the end */ Iterator end(); /** * the number of items in the list */ uint count()const; T operator[]( uint i ); int uidAt(uint i ); // FIXME implemenent remove /* ConstIterator begin()const; ConstIterator end()const; */ private: QArray<int> m_ids; const Base* m_acc; }; /* ok now implement it */ template <class T> ORecordListIterator<T>::ORecordListIterator() { m_current = 0; m_temp = 0l; m_end = true; m_record = T(); /* forward */ m_direction = TRUE; } template <class T> ORecordListIterator<T>::~ORecordListIterator() { /* nothing to delete */ } template <class T> ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) { // qWarning("ORecordListIterator copy c'tor"); m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; m_direction = it.m_direction; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) { m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; return *this; } template <class T> T ORecordListIterator<T>::operator*() { qWarning("operator* %d %d", m_current, m_uids[m_current] ); if (!m_end ) m_record = m_temp->find( m_uids[m_current], m_uids, m_current, m_direction ? Base::Forward : Base::Reverse ); else m_record = T(); return m_record; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator++() { m_direction = true; if (m_current < m_uids.count() ) { m_end = false; ++m_current; }else m_end = true; return *this; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator--() { m_direction = false; if ( m_current > 0 ) { --m_current; m_end = false; } else m_end = true; return *this; } template <class T> bool ORecordListIterator<T>::operator==( const ORecordListIterator<T>& it ) { /* if both are at we're the same.... */ if ( m_end == it.m_end ) return true; if ( m_uids != it.m_uids ) return false; if ( m_current != it.m_current ) return false; if ( m_temp != it.m_temp ) return false; return true; } template <class T> bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) { return !(*this == it ); } template <class T> ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids, const Base* t ) : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ), m_direction( false ) { } template <class T> uint ORecordListIterator<T>::current()const { return m_current; } template <class T> void ORecordListIterator<T>::setCurrent( uint cur ) { if( cur < m_uids.count() ) { m_end = false; m_current= cur; } } template <class T> uint ORecordListIterator<T>::count()const { return m_uids.count(); } template <class T> ORecordList<T>::ORecordList( const QArray<int>& ids, const Base* acc ) : m_ids( ids ), m_acc( acc ) { } template <class T> ORecordList<T>::~ORecordList() { /* nothing to do here */ } template <class T> ORecordList<T>::Iterator ORecordList<T>::begin() { Iterator it( m_ids, m_acc ); return it; } template <class T> ORecordList<T>::Iterator ORecordList<T>::end() { Iterator it( m_ids, m_acc ); it.m_end = true; it.m_current = m_ids.count(); return it; } template <class T> uint ORecordList<T>::count()const { return m_ids.count(); } template <class T> T ORecordList<T>::operator[]( uint i ) { + if ( i < 0 || (i+1) > m_ids.count() ) + return T(); /* forward */ return m_acc->find( m_ids[i], m_ids, i ); } template <class T> int ORecordList<T>::uidAt( uint i ) { return m_ids[i]; } #endif diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp new file mode 100644 index 0000000..6c81f8f --- a/dev/null +++ b/libopie/pim/orecur.cpp @@ -0,0 +1,127 @@ +#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; + hasEnd = FALSE; + end = 0; + } + char days; // Q_UINT8 for 8 seven days;) + ORecur::RepeatType type; + int freq; + int pos; + bool hasEnd : 1; + time_t end; + time_t create; +}; + + +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) { + re.data->ref(); + deref(); + data = re.data; + + return *this; +} +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(); +} +time_t ORecur::endDateUTC()const { + return data->end; +} +time_t ORecur::createTime()const { + return data->create; +} +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; +} +void ORecur::setCreateTime( time_t t) { + checkOrModify(); + data->create = t; +} +void ORecur::setHasEndDate( bool b) { + checkOrModify(); + data->hasEnd = b; +} +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; + data = d2; + } +} + diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h new file mode 100644 index 0000000..89258f8 --- a/dev/null +++ b/libopie/pim/orecur.h @@ -0,0 +1,54 @@ +/* + * GPL from TT + */ + +#ifndef OPIE_RECUR_H +#define OPIE_RECUR_H + +#include <sys/types.h> + +#include <qdatetime.h> + + + +class ORecur { +public: + 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; + RepeatType type()const; + int frequency()const; + int position()const; + char days()const; + bool hasEndDate()const; + QDate endDate()const; + time_t endDateUTC()const; + time_t createTime()const; + + void setType( const RepeatType& ); + void setFrequency( int freq ); + void setPosition( int pos ); + void setDays( char c); + void setEndDate( const QDate& dt ); + void setEndDateUTC( time_t ); + void setCreateTime( time_t ); + void setHasEndDate( bool b ); +private: + void deref(); + inline void checkOrModify(); + + + class Data; + Data* data; + class ORecurPrivate; + ORecurPrivate *d; +}; + +#endif diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index 8c2ea3a..761d7d8 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp @@ -232,309 +232,309 @@ namespace { } QString EffQuery::out()const { QString str; str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) : OTodoAccessBackend(), m_dict(15), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ } bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; return true; } bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ return m_driver->close(); } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); return m_uids; } QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int ){ QArray<int> ints(0); return ints; } OTodo OTodoAccessBackendSQL::find(int uid ) const{ FindQuery query( uid ); return todo( m_driver->query(&query) ); } OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, uint cur, Frontend::CacheDirection dir ) const{ int CACHE = readAhead(); qWarning("searching for %d", uid ); QArray<int> search( CACHE ); uint size =0; OTodo to; // we try to cache CACHE items switch( dir ) { /* forward */ case 0: for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { qWarning("size %d %d", size, ints[i] ); search[size] = ints[i]; size++; } break; /* reverse */ case 1: for (uint i = cur; i != 0 && size < CACHE; i-- ) { search[size] = ints[i]; size++; } break; } search.resize( size ); FindQuery query( search ); OSQLResult res = m_driver->query( &query ); if ( res.state() != OSQLResult::Success ) return to; return todo( res ); } void OTodoAccessBackendSQL::clear() { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); CreateQuery qu; res = m_driver->query(&qu); } bool OTodoAccessBackendSQL::add( const OTodo& t) { InsertQuery ins( t ); OSQLResult res = m_driver->query( &ins ); if ( res.state() == OSQLResult::Failure ) return false; int c = m_uids.count(); m_uids.resize( c+1 ); m_uids[c] = t.uid(); return true; } bool OTodoAccessBackendSQL::remove( int uid ) { RemoveQuery rem( uid ); OSQLResult res = m_driver->query(&rem ); if ( res.state() == OSQLResult::Failure ) return false; m_dirty = true; return true; } /* * FIXME better set query * but we need the cache for that * now we remove */ bool OTodoAccessBackendSQL::replace( const OTodo& t) { remove( t.uid() ); bool b= add(t); m_dirty = false; // we changed some stuff but the UID stayed the same return b; } QArray<int> OTodoAccessBackendSQL::overDue() { OverDueQuery qu; return uids( m_driver->query(&qu ) ); } QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, const QDate& t, bool u) { EffQuery ef(s, t, u ); return uids (m_driver->query(&ef) ); } /* * */ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { qWarning("sorted %d, %d", asc, sortOrder ); QString query; query = "select uid from todolist WHERE "; /* * Sort Filter stuff * not that straight forward * */ /* Category */ if ( sortFilter & 1 ) { QString str; if (cat != 0 ) str = QString::number( cat ); query += " categories like '%" +str+"%' AND"; } /* Show only overdue */ if ( sortFilter & 2 ) { QDate date = QDate::currentDate(); QString due; QString base; base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); query += " " + base + " AND"; } /* not show completed */ if ( sortFilter & 4 ) { query += " completed = 0 AND"; }else{ query += " ( completed = 1 OR completed = 0) AND"; } /* srtip the end */ query = query.remove( query.length()-3, 3 ); /* * sort order stuff * quite straight forward */ query += "ORDER BY "; switch( sortOrder ) { /* completed */ case 0: query += "completed"; break; case 1: query += "priority"; break; case 2: - query += "description"; + query += "summary"; break; case 3: query += "DueDate"; break; } if ( !asc ) { qWarning("not ascending!"); query += " DESC"; } qWarning( query ); OSQLRawQuery raw(query ); return uids( m_driver->query(&raw) ); } bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ if ( str == "0-0-0" ) return false; else{ int day, year, month; QStringList list = QStringList::split("-", str ); year = list[0].toInt(); month = list[1].toInt(); day = list[2].toInt(); da.setYMD( year, month, day ); return true; } } OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ if ( res.state() == OSQLResult::Failure ) { OTodo to; return to; } OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); qWarning("todo1"); OTodo to = todo( (*it) ); cache( to ); ++it; for ( ; it != list.end(); ++it ) { qWarning("caching"); cache( todo( (*it) ) ); } return to; } OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { qWarning("todo"); bool has = false; QDate da = QDate::currentDate(); has = date( da, item.data("DueDate") ); QStringList cats = QStringList::split(";", item.data("categories") ); OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), cats, item.data("summary"), item.data("description"), item.data("progress").toUShort(), has, da, item.data("uid").toInt() ); return to; } OTodo OTodoAccessBackendSQL::todo( int uid )const { FindQuery find( uid ); return todo( m_driver->query(&find) ); } /* * update the dict */ void OTodoAccessBackendSQL::fillDict() { /* initialize dict */ /* * UPDATE dict if you change anything!!! */ m_dict.setAutoDelete( TRUE ); m_dict.insert("Categories" , new int(OTodo::Category) ); m_dict.insert("Uid" , new int(OTodo::Uid) ); m_dict.insert("HasDate" , new int(OTodo::HasDate) ); m_dict.insert("Completed" , new int(OTodo::Completed) ); m_dict.insert("Description" , new int(OTodo::Description) ); m_dict.insert("Summary" , new int(OTodo::Summary) ); m_dict.insert("Priority" , new int(OTodo::Priority) ); m_dict.insert("DateDay" , new int(OTodo::DateDay) ); m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); m_dict.insert("DateYear" , new int(OTodo::DateYear) ); m_dict.insert("Progress" , new int(OTodo::Progress) ); m_dict.insert("Completed", new int(OTodo::Completed) ); m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); } /* * need to be const so let's fool the * compiler :( */ void OTodoAccessBackendSQL::update()const { ((OTodoAccessBackendSQL*)this)->m_dirty = false; LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); } QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); qWarning(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } return ints; } diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 8c2ea3a..761d7d8 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp @@ -232,309 +232,309 @@ namespace { } QString EffQuery::out()const { QString str; str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) : OTodoAccessBackend(), m_dict(15), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ } bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; return true; } bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ return m_driver->close(); } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); return m_uids; } QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int ){ QArray<int> ints(0); return ints; } OTodo OTodoAccessBackendSQL::find(int uid ) const{ FindQuery query( uid ); return todo( m_driver->query(&query) ); } OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, uint cur, Frontend::CacheDirection dir ) const{ int CACHE = readAhead(); qWarning("searching for %d", uid ); QArray<int> search( CACHE ); uint size =0; OTodo to; // we try to cache CACHE items switch( dir ) { /* forward */ case 0: for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { qWarning("size %d %d", size, ints[i] ); search[size] = ints[i]; size++; } break; /* reverse */ case 1: for (uint i = cur; i != 0 && size < CACHE; i-- ) { search[size] = ints[i]; size++; } break; } search.resize( size ); FindQuery query( search ); OSQLResult res = m_driver->query( &query ); if ( res.state() != OSQLResult::Success ) return to; return todo( res ); } void OTodoAccessBackendSQL::clear() { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); CreateQuery qu; res = m_driver->query(&qu); } bool OTodoAccessBackendSQL::add( const OTodo& t) { InsertQuery ins( t ); OSQLResult res = m_driver->query( &ins ); if ( res.state() == OSQLResult::Failure ) return false; int c = m_uids.count(); m_uids.resize( c+1 ); m_uids[c] = t.uid(); return true; } bool OTodoAccessBackendSQL::remove( int uid ) { RemoveQuery rem( uid ); OSQLResult res = m_driver->query(&rem ); if ( res.state() == OSQLResult::Failure ) return false; m_dirty = true; return true; } /* * FIXME better set query * but we need the cache for that * now we remove */ bool OTodoAccessBackendSQL::replace( const OTodo& t) { remove( t.uid() ); bool b= add(t); m_dirty = false; // we changed some stuff but the UID stayed the same return b; } QArray<int> OTodoAccessBackendSQL::overDue() { OverDueQuery qu; return uids( m_driver->query(&qu ) ); } QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, const QDate& t, bool u) { EffQuery ef(s, t, u ); return uids (m_driver->query(&ef) ); } /* * */ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { qWarning("sorted %d, %d", asc, sortOrder ); QString query; query = "select uid from todolist WHERE "; /* * Sort Filter stuff * not that straight forward * */ /* Category */ if ( sortFilter & 1 ) { QString str; if (cat != 0 ) str = QString::number( cat ); query += " categories like '%" +str+"%' AND"; } /* Show only overdue */ if ( sortFilter & 2 ) { QDate date = QDate::currentDate(); QString due; QString base; base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); query += " " + base + " AND"; } /* not show completed */ if ( sortFilter & 4 ) { query += " completed = 0 AND"; }else{ query += " ( completed = 1 OR completed = 0) AND"; } /* srtip the end */ query = query.remove( query.length()-3, 3 ); /* * sort order stuff * quite straight forward */ query += "ORDER BY "; switch( sortOrder ) { /* completed */ case 0: query += "completed"; break; case 1: query += "priority"; break; case 2: - query += "description"; + query += "summary"; break; case 3: query += "DueDate"; break; } if ( !asc ) { qWarning("not ascending!"); query += " DESC"; } qWarning( query ); OSQLRawQuery raw(query ); return uids( m_driver->query(&raw) ); } bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ if ( str == "0-0-0" ) return false; else{ int day, year, month; QStringList list = QStringList::split("-", str ); year = list[0].toInt(); month = list[1].toInt(); day = list[2].toInt(); da.setYMD( year, month, day ); return true; } } OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ if ( res.state() == OSQLResult::Failure ) { OTodo to; return to; } OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); qWarning("todo1"); OTodo to = todo( (*it) ); cache( to ); ++it; for ( ; it != list.end(); ++it ) { qWarning("caching"); cache( todo( (*it) ) ); } return to; } OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { qWarning("todo"); bool has = false; QDate da = QDate::currentDate(); has = date( da, item.data("DueDate") ); QStringList cats = QStringList::split(";", item.data("categories") ); OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), cats, item.data("summary"), item.data("description"), item.data("progress").toUShort(), has, da, item.data("uid").toInt() ); return to; } OTodo OTodoAccessBackendSQL::todo( int uid )const { FindQuery find( uid ); return todo( m_driver->query(&find) ); } /* * update the dict */ void OTodoAccessBackendSQL::fillDict() { /* initialize dict */ /* * UPDATE dict if you change anything!!! */ m_dict.setAutoDelete( TRUE ); m_dict.insert("Categories" , new int(OTodo::Category) ); m_dict.insert("Uid" , new int(OTodo::Uid) ); m_dict.insert("HasDate" , new int(OTodo::HasDate) ); m_dict.insert("Completed" , new int(OTodo::Completed) ); m_dict.insert("Description" , new int(OTodo::Description) ); m_dict.insert("Summary" , new int(OTodo::Summary) ); m_dict.insert("Priority" , new int(OTodo::Priority) ); m_dict.insert("DateDay" , new int(OTodo::DateDay) ); m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); m_dict.insert("DateYear" , new int(OTodo::DateYear) ); m_dict.insert("Progress" , new int(OTodo::Progress) ); m_dict.insert("Completed", new int(OTodo::Completed) ); m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); } /* * need to be const so let's fool the * compiler :( */ void OTodoAccessBackendSQL::update()const { ((OTodoAccessBackendSQL*)this)->m_dirty = false; LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); } QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); qWarning(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } return ints; } diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp new file mode 100644 index 0000000..6c81f8f --- a/dev/null +++ b/libopie2/opiepim/core/orecur.cpp @@ -0,0 +1,127 @@ +#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; + hasEnd = FALSE; + end = 0; + } + char days; // Q_UINT8 for 8 seven days;) + ORecur::RepeatType type; + int freq; + int pos; + bool hasEnd : 1; + time_t end; + time_t create; +}; + + +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) { + re.data->ref(); + deref(); + data = re.data; + + return *this; +} +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(); +} +time_t ORecur::endDateUTC()const { + return data->end; +} +time_t ORecur::createTime()const { + return data->create; +} +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; +} +void ORecur::setCreateTime( time_t t) { + checkOrModify(); + data->create = t; +} +void ORecur::setHasEndDate( bool b) { + checkOrModify(); + data->hasEnd = b; +} +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; + data = d2; + } +} + diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h new file mode 100644 index 0000000..89258f8 --- a/dev/null +++ b/libopie2/opiepim/core/orecur.h @@ -0,0 +1,54 @@ +/* + * GPL from TT + */ + +#ifndef OPIE_RECUR_H +#define OPIE_RECUR_H + +#include <sys/types.h> + +#include <qdatetime.h> + + + +class ORecur { +public: + 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; + RepeatType type()const; + int frequency()const; + int position()const; + char days()const; + bool hasEndDate()const; + QDate endDate()const; + time_t endDateUTC()const; + time_t createTime()const; + + void setType( const RepeatType& ); + void setFrequency( int freq ); + void setPosition( int pos ); + void setDays( char c); + void setEndDate( const QDate& dt ); + void setEndDateUTC( time_t ); + void setCreateTime( time_t ); + void setHasEndDate( bool b ); +private: + void deref(); + inline void checkOrModify(); + + + class Data; + Data* data; + class ORecurPrivate; + ORecurPrivate *d; +}; + +#endif diff --git a/libopie2/opiepim/orecordlist.h b/libopie2/opiepim/orecordlist.h index 5404910..e377447 100644 --- a/libopie2/opiepim/orecordlist.h +++ b/libopie2/opiepim/orecordlist.h @@ -71,200 +71,202 @@ private: bool m_direction :1; /* d pointer for future versions */ class IteratorPrivate; IteratorPrivate *d; }; /** * The recordlist used as a return type * from OPimAccessTemplate */ template <class T = OPimRecord > class ORecordList { public: typedef OTemplateBase<T> Base; typedef ORecordListIterator<T> Iterator; /** * c'tor */ ORecordList () { } ORecordList( const QArray<int>& ids, const Base* ); ~ORecordList(); /** * the first iterator */ Iterator begin(); /** * the end */ Iterator end(); /** * the number of items in the list */ uint count()const; T operator[]( uint i ); int uidAt(uint i ); // FIXME implemenent remove /* ConstIterator begin()const; ConstIterator end()const; */ private: QArray<int> m_ids; const Base* m_acc; }; /* ok now implement it */ template <class T> ORecordListIterator<T>::ORecordListIterator() { m_current = 0; m_temp = 0l; m_end = true; m_record = T(); /* forward */ m_direction = TRUE; } template <class T> ORecordListIterator<T>::~ORecordListIterator() { /* nothing to delete */ } template <class T> ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) { // qWarning("ORecordListIterator copy c'tor"); m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; m_direction = it.m_direction; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) { m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; return *this; } template <class T> T ORecordListIterator<T>::operator*() { qWarning("operator* %d %d", m_current, m_uids[m_current] ); if (!m_end ) m_record = m_temp->find( m_uids[m_current], m_uids, m_current, m_direction ? Base::Forward : Base::Reverse ); else m_record = T(); return m_record; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator++() { m_direction = true; if (m_current < m_uids.count() ) { m_end = false; ++m_current; }else m_end = true; return *this; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator--() { m_direction = false; if ( m_current > 0 ) { --m_current; m_end = false; } else m_end = true; return *this; } template <class T> bool ORecordListIterator<T>::operator==( const ORecordListIterator<T>& it ) { /* if both are at we're the same.... */ if ( m_end == it.m_end ) return true; if ( m_uids != it.m_uids ) return false; if ( m_current != it.m_current ) return false; if ( m_temp != it.m_temp ) return false; return true; } template <class T> bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) { return !(*this == it ); } template <class T> ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids, const Base* t ) : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ), m_direction( false ) { } template <class T> uint ORecordListIterator<T>::current()const { return m_current; } template <class T> void ORecordListIterator<T>::setCurrent( uint cur ) { if( cur < m_uids.count() ) { m_end = false; m_current= cur; } } template <class T> uint ORecordListIterator<T>::count()const { return m_uids.count(); } template <class T> ORecordList<T>::ORecordList( const QArray<int>& ids, const Base* acc ) : m_ids( ids ), m_acc( acc ) { } template <class T> ORecordList<T>::~ORecordList() { /* nothing to do here */ } template <class T> ORecordList<T>::Iterator ORecordList<T>::begin() { Iterator it( m_ids, m_acc ); return it; } template <class T> ORecordList<T>::Iterator ORecordList<T>::end() { Iterator it( m_ids, m_acc ); it.m_end = true; it.m_current = m_ids.count(); return it; } template <class T> uint ORecordList<T>::count()const { return m_ids.count(); } template <class T> T ORecordList<T>::operator[]( uint i ) { + if ( i < 0 || (i+1) > m_ids.count() ) + return T(); /* forward */ return m_acc->find( m_ids[i], m_ids, i ); } template <class T> int ORecordList<T>::uidAt( uint i ) { return m_ids[i]; } #endif |