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