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

orecurrancewidget.cpp

Go to the documentation of this file.
00001 #include <qapplication.h>
00002 #include <qlabel.h>
00003 #include <qspinbox.h>
00004 
00005 
00006 #include "orecurrancewidget.h"
00007 
00008 // Global Templates for use in setting up the repeat label...
00009 // the problem is these strings get initialized before QPEApplication can install the translator -zecke
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  * static linkage to not polute the symbol table...
00021  * The problem is that const and static linkage are resolved prior to installing a translator
00022  * leading to that the above strings are translted but to the original we delay the init of these strings...
00023  * -zecke
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 );  // return the proper word format for
00041                                         // x (1st, 2nd, etc)
00042 static int week( const QDate &dt );    // what week in the month is 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     // do some stuff with the repeat pattern
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                 // figure out the montly day...
00223                 rpTmp.setPosition(  week( start ) );
00224                 break;
00225             case Year:
00226                 rpTmp.setType( ORecur::Yearly );
00227                 break;
00228             }
00229             break;  // no need to keep looking!
00230         }
00231     }
00232     rpTmp.setFrequency(spinFreq->value() );
00233     rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
00234     if ( rpTmp.hasEndDate() ) {
00235         rpTmp.setEndDate( end );
00236     }
00237     // timestamp it...
00238 //    rpTmp.setCreateTime(  ); current DateTime is already set -zecke
00239     return rpTmp;
00240 }
00241 
00246 QDate ORecurranceWidget::endDate()const {
00247     return end;
00248 }
00249 void ORecurranceWidget::slotSetRType(int rtype) {
00250    // now call the right function based on the type...
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     // if the item was toggled, then go ahead and set it to the maximum date
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     // change the spelling based on the value of x
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     // don't do something we'll regret!!!
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         // a crazy check, if you are repeating weekly, the current day
00351         // must be selected!!!
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     // we need to make this unintrusive as possible...
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 // reshow the buttons...
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     // I hope clustering these improve performance....
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     // might as well set the day too...
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       // hide the extra buttons...
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     // figure out the week...
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     // I hope this works in other languages besides english...
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 }

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