00001 #include <qapplication.h>
00002 #include <qlabel.h>
00003 #include <qpopupmenu.h>
00004 #include <qspinbox.h>
00005
00006 #include <qpe/timestring.h>
00007
00008 #include "opimrecurrencewidget.h"
00009
00010
00011 using namespace Opie;
00012
00013
00014 namespace {
00015 QString strDayTemplate;
00016 QString strYearTemplate;
00017 QString strMonthDateTemplate;
00018 QString strMonthDayTemplate;
00019 QString strWeekTemplate;
00020 QString dayLabel[7];
00021 }
00022
00023
00024
00025
00026
00027
00028
00029 static void fillStrings() {
00030 strDayTemplate = QObject::tr("Every");
00031 strYearTemplate = QObject::tr("%1 %2 every ");
00032 strMonthDateTemplate = QObject::tr("The %1 every ");
00033 strMonthDayTemplate = QObject::tr("The %1 %2 of every");
00034 strWeekTemplate = QObject::tr("Every ");
00035 dayLabel[0] = QObject::tr("Monday");
00036 dayLabel[1] = QObject::tr("Tuesday");
00037 dayLabel[2] = QObject::tr("Wednesday");
00038 dayLabel[3] = QObject::tr("Thursday");
00039 dayLabel[4] = QObject::tr("Friday");
00040 dayLabel[5] = QObject::tr("Saturday");
00041 dayLabel[6] = QObject::tr("Sunday");
00042 }
00043
00044 static QString numberPlacing( int x );
00045
00046 static int week( const QDate &dt );
00047
00057 OPimRecurrenceWidget::OPimRecurrenceWidget( bool startOnMonday,
00058 const QDate& newStart,
00059 QWidget* parent,
00060 const char* name,
00061 bool modal,
00062 WFlags fl )
00063 : OPimRecurrenceBase( parent, name, modal, fl ),
00064 start( newStart ),
00065 currInterval( None ),
00066 startWeekOnMonday( startOnMonday )
00067 {
00068 if (strDayTemplate.isEmpty() )
00069 fillStrings();
00070
00071 init();
00072 fraType->setButton( currInterval );
00073 chkNoEnd->setChecked( TRUE );
00074 setupNone();
00075 }
00076
00087 OPimRecurrenceWidget::OPimRecurrenceWidget( bool startOnMonday,
00088 const Opie::OPimRecurrence& rp, const QDate& startDate,
00089 QWidget* parent, const char* name,
00090 bool modal, WFlags fl)
00091 : OPimRecurrenceBase( parent, name, modal, fl ),
00092 start( startDate ),
00093 end( rp.endDate() ),
00094 startWeekOnMonday( startOnMonday )
00095 {
00096 if (strDayTemplate.isEmpty() )
00097 fillStrings();
00098
00099 init();
00100 setRecurrence( rp );
00101 }
00102
00103 OPimRecurrenceWidget::~OPimRecurrenceWidget() {
00104 }
00105
00110 void OPimRecurrenceWidget::setStartDate( const QDate& date ) {
00111 setRecurrence( recurrence(), date );
00112 }
00117 void OPimRecurrenceWidget::setRecurrence( const Opie::OPimRecurrence& rp ) {
00118 setRecurrence( rp, start );
00119 }
00120
00126 void OPimRecurrenceWidget::setRecurrence( const Opie::OPimRecurrence& rp, const QDate& date ) {
00127 start = date;
00128 end = rp.endDate();
00129 switch ( rp.type() ) {
00130 default:
00131 case OPimRecurrence::NoRepeat:
00132 currInterval = None;
00133 setupNone();
00134 break;
00135 case OPimRecurrence::Daily:
00136 currInterval = Day;
00137 setupDaily();
00138 break;
00139 case OPimRecurrence::Weekly:
00140 currInterval = Week;
00141 setupWeekly();
00142 int day, buttons;
00143 for ( day = 0x01, buttons = 0; buttons < 7;
00144 day = day << 1, buttons++ ) {
00145 if ( rp.days() & day ) {
00146 if ( startWeekOnMonday )
00147 fraExtra->setButton( buttons );
00148 else {
00149 if ( buttons == 7 )
00150 fraExtra->setButton( 0 );
00151 else
00152 fraExtra->setButton( buttons + 1 );
00153 }
00154 }
00155 }
00156 slotWeekLabel();
00157 break;
00158 case OPimRecurrence::MonthlyDay:
00159 currInterval = Month;
00160 setupMonthly();
00161 fraExtra->setButton( 0 );
00162 slotMonthLabel( 0 );
00163 break;
00164 case OPimRecurrence::MonthlyDate:
00165 currInterval = Month;
00166 setupMonthly();
00167 fraExtra->setButton( 1 );
00168 slotMonthLabel( 1 );
00169 break;
00170 case OPimRecurrence::Yearly:
00171 currInterval = Year;
00172 setupYearly();
00173 break;
00174 }
00175 fraType->setButton( currInterval );
00176 spinFreq->setValue( rp.frequency() );
00177 if ( !rp.hasEndDate() ) {
00178 cmdEnd->setText( tr("No End Date") );
00179 chkNoEnd->setChecked( TRUE );
00180 } else
00181 cmdEnd->setText( TimeString::shortDate( end ) );
00182 }
00183
00188 OPimRecurrence OPimRecurrenceWidget::recurrence()const {
00189 QListIterator<QToolButton> it( listRTypeButtons );
00190 QListIterator<QToolButton> itExtra( listExtra );
00191 OPimRecurrence rpTmp;
00192 int i;
00193 for ( i = 0; *it; ++it, i++ ) {
00194 if ( (*it)->isOn() ) {
00195 switch ( i ) {
00196 case None:
00197 rpTmp.setType( OPimRecurrence::NoRepeat );
00198 break;
00199 case Day:
00200 rpTmp.setType( OPimRecurrence::Daily );
00201 break;
00202 case Week:{
00203 rpTmp.setType( OPimRecurrence::Weekly );
00204 int day;
00205 int day2 = 0;
00206 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
00207 if ( (*itExtra)->isOn() ) {
00208 if ( startWeekOnMonday )
00209 day2 |= day;
00210 else {
00211 if ( day == 1 )
00212 day2 |= Event::SUN;
00213 else
00214 day2 |= day >> 1;
00215 }
00216 }
00217 }
00218 rpTmp.setDays( day2 );
00219 }
00220 break;
00221 case Month:
00222 if ( cmdExtra1->isOn() )
00223 rpTmp.setType( OPimRecurrence::MonthlyDay );
00224 else if ( cmdExtra2->isOn() )
00225 rpTmp.setType( OPimRecurrence::MonthlyDate );
00226
00227 rpTmp.setPosition( week( start ) );
00228 break;
00229 case Year:
00230 rpTmp.setType( OPimRecurrence::Yearly );
00231 break;
00232 }
00233 break;
00234 }
00235 }
00236 rpTmp.setFrequency(spinFreq->value() );
00237 rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
00238 if ( rpTmp.hasEndDate() ) {
00239 rpTmp.setEndDate( end );
00240 }
00241
00242
00243 return rpTmp;
00244 }
00245
00250 QDate OPimRecurrenceWidget::endDate()const {
00251 return end;
00252 }
00253 void OPimRecurrenceWidget::slotSetRType(int rtype) {
00254
00255 currInterval = static_cast<repeatButtons>(rtype);
00256 switch ( currInterval ) {
00257 case None:
00258 setupNone();
00259 break;
00260 case Day:
00261 setupDaily();
00262 break;
00263 case Week:
00264 setupWeekly();
00265 slotWeekLabel();
00266 break;
00267 case Month:
00268 setupMonthly();
00269 cmdExtra2->setOn( TRUE );
00270 slotMonthLabel( 1 );
00271 break;
00272 case Year:
00273 setupYearly();
00274 break;
00275 }
00276 }
00277 void OPimRecurrenceWidget::endDateChanged(int y, int m, int d) {
00278 end.setYMD( y, m, d );
00279 if ( end < start )
00280 end = start;
00281 cmdEnd->setText( TimeString::shortDate( end ) );
00282 repeatPicker->setDate( end.year(), end.month(), end.day() );
00283 }
00284 void OPimRecurrenceWidget::slotNoEnd( bool unused) {
00285
00286 if ( unused ) {
00287 end.setYMD( 3000, 12, 31 );
00288 cmdEnd->setText( tr("No End Date") );
00289 } else {
00290 end = start;
00291 cmdEnd->setText( TimeString::shortDate(end) );
00292 }
00293 }
00294 void OPimRecurrenceWidget::setupRepeatLabel( const QString& s) {
00295 lblVar1->setText( s );
00296 }
00297 void OPimRecurrenceWidget::setupRepeatLabel( int x) {
00298
00299 QString strVar2;
00300
00301 if ( x > 1 )
00302 lblVar1->show();
00303 else
00304 lblVar1->hide();
00305
00306 switch ( currInterval ) {
00307 case None:
00308 break;
00309 case Day:
00310 if ( x > 1 )
00311 strVar2 = tr( "days" );
00312 else
00313 strVar2 = tr( "day" );
00314 break;
00315 case Week:
00316 if ( x > 1 )
00317 strVar2 = tr( "weeks" );
00318 else
00319 strVar2 = tr( "week" );
00320 break;
00321 case Month:
00322 if ( x > 1 )
00323 strVar2 = tr( "months" );
00324 else
00325 strVar2 = tr( "month" );
00326 break;
00327 case Year:
00328 if ( x > 1 )
00329 strVar2 = tr( "years" );
00330 else
00331 strVar2 = tr( "year" );
00332 break;
00333 }
00334 if ( !strVar2.isNull() )
00335 lblVar2->setText( strVar2 );
00336 }
00337 void OPimRecurrenceWidget::slotWeekLabel() {
00338 QString str;
00339 QListIterator<QToolButton> it( listExtra );
00340 unsigned int i;
00341 unsigned int keepMe;
00342 bool bNeedCarriage = FALSE;
00343
00344 if ( currInterval != Week )
00345 return;
00346
00347 if ( startWeekOnMonday )
00348 keepMe = start.dayOfWeek() - 1;
00349 else
00350 keepMe = start.dayOfWeek() % 7;
00351
00352 QStringList list;
00353 for ( i = 0; *it; ++it, i++ ) {
00354
00355
00356 if ( i == keepMe && !( (*it)->isOn() ) )
00357 (*it)->setOn( TRUE );
00358 if ( (*it)->isOn() ) {
00359 if ( startWeekOnMonday )
00360 list.append( dayLabel[i] );
00361 else {
00362 if ( i == 0 )
00363 list.append( dayLabel[6] );
00364 else
00365 list.append( dayLabel[i - 1] );
00366 }
00367 }
00368 }
00369 QStringList::Iterator itStr;
00370 for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
00371 if ( i == 3 )
00372 bNeedCarriage = TRUE;
00373 else
00374 bNeedCarriage = FALSE;
00375 if ( str.isNull() )
00376 str = *itStr;
00377 else if ( i == list.count() - 1 ) {
00378 if ( i < 2 )
00379 str += tr(" and ") + *itStr;
00380 else {
00381 if ( bNeedCarriage )
00382 str += tr( ",\nand " ) + *itStr;
00383 else
00384 str += tr( ", and " ) + *itStr;
00385 }
00386 } else {
00387 if ( bNeedCarriage )
00388 str += ",\n" + *itStr;
00389 else
00390 str += ", " + *itStr;
00391 }
00392 }
00393 str = str.prepend( tr("on ") );
00394
00395 lblWeekVar->setText( str );
00396 }
00397 void OPimRecurrenceWidget::slotMonthLabel(int type) {
00398 QString str;
00399 if ( currInterval != Month || type > 1 )
00400 return;
00401 if ( type == 1 )
00402 str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
00403 else
00404 str = strMonthDayTemplate.arg( numberPlacing(week(start)))
00405 .arg( dayLabel[start.dayOfWeek() - 1] );
00406 lblRepeat->setText( str );
00407 }
00408 void OPimRecurrenceWidget::slotChangeStartOfWeek( bool onMonday ) {
00409 startWeekOnMonday = onMonday;
00410
00411 int saveSpin = spinFreq->value();
00412 char days = 0;
00413 int day;
00414 QListIterator<QToolButton> itExtra( listExtra );
00415 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
00416 if ( (*itExtra)->isOn() ) {
00417 if ( !startWeekOnMonday )
00418 days |= day;
00419 else {
00420 if ( day == 1 )
00421 days |= OPimRecurrence::SUN;
00422 else
00423 days |= day >> 1;
00424 }
00425 }
00426 }
00427 setupWeekly();
00428 spinFreq->setValue( saveSpin );
00429 int buttons;
00430 for ( day = 0x01, buttons = 0; buttons < 7;
00431 day = day << 1, buttons++ ) {
00432 if ( days & day ) {
00433 if ( startWeekOnMonday )
00434 fraExtra->setButton( buttons );
00435 else {
00436 if ( buttons == 7 )
00437 fraExtra->setButton( 0 );
00438 else
00439 fraExtra->setButton( buttons + 1 );
00440 }
00441 }
00442 }
00443 slotWeekLabel();
00444 }
00445 void OPimRecurrenceWidget::setupNone() {
00446 lblRepeat->setText( tr("No Repeat") );
00447 lblVar1->hide();
00448 lblVar2->hide();
00449 hideExtras();
00450 cmdEnd->hide();
00451 lblFreq->hide();
00452 lblEvery->hide();
00453 lblFreq->hide();
00454 spinFreq->hide();
00455 lblEnd->hide();
00456 lblWeekVar->hide();
00457 }
00458 void OPimRecurrenceWidget::setupDaily() {
00459 hideExtras();
00460 lblWeekVar->hide();
00461 spinFreq->setValue( 1 );
00462 lblFreq->setText( tr("day(s)") );
00463 lblVar2->show();
00464 showRepeatStuff();
00465 lblRepeat->setText( strDayTemplate );
00466 setupRepeatLabel( 1 );
00467 }
00468 void OPimRecurrenceWidget::setupWeekly() {
00469
00470 fraExtra->setTitle( tr("Repeat On") );
00471 fraExtra->setExclusive( FALSE );
00472 fraExtra->show();
00473 if ( startWeekOnMonday ) {
00474 cmdExtra1->setText( tr("Mon") );
00475 cmdExtra2->setText( tr("Tue") );
00476 cmdExtra3->setText( tr("Wed") );
00477 cmdExtra4->setText( tr("Thu") );
00478 cmdExtra5->setText( tr("Fri") );
00479 cmdExtra6->setText( tr("Sat") );
00480 cmdExtra7->setText( tr("Sun") );
00481 } else {
00482 cmdExtra1->setText( tr("Sun") );
00483 cmdExtra2->setText( tr("Mon") );
00484 cmdExtra3->setText( tr("Tue") );
00485 cmdExtra4->setText( tr("Wed") );
00486 cmdExtra5->setText( tr("Thu") );
00487 cmdExtra6->setText( tr("Fri") );
00488 cmdExtra7->setText( tr("Sat") );
00489 }
00490
00491 cmdExtra1->setOn( FALSE );
00492 cmdExtra2->setOn( FALSE );
00493 cmdExtra3->setOn( FALSE );
00494 cmdExtra4->setOn( FALSE );
00495 cmdExtra5->setOn( FALSE );
00496 cmdExtra6->setOn( FALSE );
00497 cmdExtra7->setOn( FALSE );
00498
00499 cmdExtra1->show();
00500 cmdExtra2->show();
00501 cmdExtra3->show();
00502 cmdExtra4->show();
00503 cmdExtra5->show();
00504 cmdExtra6->show();
00505 cmdExtra7->show();
00506
00507 lblWeekVar->show();
00508 spinFreq->setValue( 1 );
00509
00510 if ( startWeekOnMonday ) {
00511 fraExtra->setButton( start.dayOfWeek() - 1 );
00512 } else {
00513 fraExtra->setButton( start.dayOfWeek() % 7 );
00514 }
00515 lblFreq->setText( tr("week(s)") );
00516 lblVar2->show();
00517 showRepeatStuff();
00518 setupRepeatLabel( 1 );
00519 }
00520 void OPimRecurrenceWidget::setupMonthly() {
00521 hideExtras();
00522 lblWeekVar->hide();
00523 fraExtra->setTitle( tr("Repeat By") );
00524 fraExtra->setExclusive( TRUE );
00525 fraExtra->show();
00526 cmdExtra1->setText( tr("Day") );
00527 cmdExtra1->show();
00528 cmdExtra2->setText( tr("Date") );
00529 cmdExtra2->show();
00530 spinFreq->setValue( 1 );
00531 lblFreq->setText( tr("month(s)") );
00532 lblVar2->show();
00533 showRepeatStuff();
00534 setupRepeatLabel( 1 );
00535 }
00536 void OPimRecurrenceWidget::setupYearly() {
00537 hideExtras();
00538 lblWeekVar->hide();
00539 spinFreq->setValue( 1 );
00540 lblFreq->setText( tr("year(s)") );
00541 lblFreq->show();
00542 lblFreq->show();
00543 showRepeatStuff();
00544 lblVar2->show();
00545 QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
00546 lblRepeat->setText( strEvery );
00547 setupRepeatLabel( 1 );
00548
00549 }
00550 void OPimRecurrenceWidget::init() {
00551 QPopupMenu *m1 = new QPopupMenu( this );
00552 repeatPicker = new DateBookMonth( m1, 0, TRUE );
00553 m1->insertItem( repeatPicker );
00554 cmdEnd->setPopup( m1 );
00555 cmdEnd->setPopupDelay( 0 );
00556
00557 QObject::connect( repeatPicker, SIGNAL(dateClicked(int,int,int)),
00558 this, SLOT(endDateChanged(int,int,int)) );
00559 QObject::connect( qApp, SIGNAL(weekChanged(bool)),
00560 this, SLOT(slotChangeStartOfWeek(bool)) );
00561
00562 listRTypeButtons.setAutoDelete( TRUE );
00563 listRTypeButtons.append( cmdNone );
00564 listRTypeButtons.append( cmdDay );
00565 listRTypeButtons.append( cmdWeek );
00566 listRTypeButtons.append( cmdMonth );
00567 listRTypeButtons.append( cmdYear );
00568
00569 listExtra.setAutoDelete( TRUE );
00570 listExtra.append( cmdExtra1 );
00571 listExtra.append( cmdExtra2 );
00572 listExtra.append( cmdExtra3 );
00573 listExtra.append( cmdExtra4 );
00574 listExtra.append( cmdExtra5 );
00575 listExtra.append( cmdExtra6 );
00576 listExtra.append( cmdExtra7 );
00577 }
00578 void OPimRecurrenceWidget::hideExtras() {
00579
00580 fraExtra->hide();
00581 chkNoEnd->hide();
00582 QListIterator<QToolButton> it( listExtra );
00583 for ( ; *it; ++it ) {
00584 (*it)->hide();
00585 (*it)->setOn( FALSE );
00586 }
00587 }
00588 void OPimRecurrenceWidget::showRepeatStuff() {
00589 cmdEnd->show();
00590 chkNoEnd->show();
00591 lblFreq->show();
00592 lblEvery->show();
00593 lblFreq->show();
00594 spinFreq->show();
00595 lblEnd->show();
00596 lblRepeat->setText( tr("Every") );
00597 }
00598
00599
00600 static int week( const QDate &start )
00601 {
00602
00603 int stop = start.day(),
00604 sentinel = start.dayOfWeek(),
00605 dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
00606 week = 1,
00607 i;
00608 for ( i = 1; i < stop; i++ ) {
00609 if ( dayOfWeek++ == sentinel )
00610 week++;
00611 if ( dayOfWeek > 7 )
00612 dayOfWeek = 0;
00613 }
00614 return week;
00615 }
00616
00617 static QString numberPlacing( int x )
00618 {
00619
00620 QString str = QString::number( x );
00621 switch ( x % 10 ) {
00622 case 1:
00623 str += QWidget::tr( "st" );
00624 break;
00625 case 2:
00626 str += QWidget::tr( "nd" );
00627 break;
00628 case 3:
00629 str += QWidget::tr( "rd" );
00630 break;
00631 default:
00632 str += QWidget::tr( "th" );
00633 break;
00634 }
00635 return str;
00636 }