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