summaryrefslogtreecommitdiff
path: root/libopie/orecurrancewidget.cpp
authorzecke <zecke>2002-10-20 12:15:51 (UTC)
committer zecke <zecke>2002-10-20 12:15:51 (UTC)
commit82689364fd558ccd28253961204e6b3eb9e32b03 (patch) (side-by-side diff)
treeaec5a649346194aa76aaadd9c7418b700ac4d3d3 /libopie/orecurrancewidget.cpp
parent7948b5910a098d05f4cc7d0fb14b0f216bf41358 (diff)
downloadopie-82689364fd558ccd28253961204e6b3eb9e32b03.zip
opie-82689364fd558ccd28253961204e6b3eb9e32b03.tar.gz
opie-82689364fd558ccd28253961204e6b3eb9e32b03.tar.bz2
Added ORecur which is a base class for Recurrance extracted from TT Event class
and a widget where you can set the Recurrance This will be used at least in Todolist and Datebook and in the common classes of OTodo and OEvent Fixed the SQL in multiple ways it's summary not description for example
Diffstat (limited to 'libopie/orecurrancewidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/orecurrancewidget.cpp556
1 files changed, 556 insertions, 0 deletions
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;
+}