Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

opimrecurrencewidget.cpp

Go to the documentation of this file.
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 // Global Templates for use in setting up the repeat label...
00013 // the problem is these strings get initialized before QPEApplication can install the translator -zecke
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  * static linkage to not polute the symbol table...
00025  * The problem is that const and static linkage are resolved prior to installing a translator
00026  * leading to that the above strings are translted but to the original we delay the init of these strings...
00027  * -zecke
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 );  // return the proper word format for
00045                                         // x (1st, 2nd, etc)
00046 static int week( const QDate &dt );    // what week in the month is 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     // do some stuff with the repeat pattern
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                 // figure out the montly day...
00227                 rpTmp.setPosition(  week( start ) );
00228                 break;
00229             case Year:
00230                 rpTmp.setType( OPimRecurrence::Yearly );
00231                 break;
00232             }
00233             break;  // no need to keep looking!
00234         }
00235     }
00236     rpTmp.setFrequency(spinFreq->value() );
00237     rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
00238     if ( rpTmp.hasEndDate() ) {
00239         rpTmp.setEndDate( end );
00240     }
00241     // timestamp it...
00242 //    rpTmp.setCreateTime(  ); current DateTime is already set -zecke
00243     return rpTmp;
00244 }
00245 
00250 QDate OPimRecurrenceWidget::endDate()const {
00251     return end;
00252 }
00253 void OPimRecurrenceWidget::slotSetRType(int rtype) {
00254    // now call the right function based on the type...
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     // if the item was toggled, then go ahead and set it to the maximum date
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     // change the spelling based on the value of x
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     // don't do something we'll regret!!!
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         // a crazy check, if you are repeating weekly, the current day
00355         // must be selected!!!
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     // we need to make this unintrusive as possible...
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 // reshow the buttons...
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     // I hope clustering these improve performance....
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     // might as well set the day too...
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       // hide the extra buttons...
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     // figure out the week...
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     // I hope this works in other languages besides english...
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 }

Generated on Sat Nov 5 16:16:23 2005 for OPIE by  doxygen 1.4.2