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