libopie API Documentation

orecurrancewidget.cpp

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 // Global Templates for use in setting up the repeat label...
00011 // the problem is these strings get initialized before QPEApplication can install the translator -zecke
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  * static linkage to not polute the symbol table...
00023  * The problem is that const and static linkage are resolved prior to installing a translator
00024  * leading to that the above strings are translted but to the original we delay the init of these strings...
00025  * -zecke
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 );  // return the proper word format for
00043                                         // x (1st, 2nd, etc)
00044 static int week( const QDate &dt );    // what week in the month is 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     // do some stuff with the repeat pattern
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                 // figure out the montly day...
00225                 rpTmp.setPosition(  week( start ) );
00226                 break;
00227             case Year:
00228                 rpTmp.setType( ORecur::Yearly );
00229                 break;
00230         }
00231         break;  // no need to keep looking!
00232     }
00233     }
00234     rpTmp.setFrequency(spinFreq->value() );
00235     rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
00236     if ( rpTmp.hasEndDate() ) {
00237     rpTmp.setEndDate( end );
00238     }
00239     // timestamp it...
00240 //    rpTmp.setCreateTime(  ); current DateTime is already set -zecke
00241     return rpTmp;
00242 }
00243 
00248 QDate ORecurranceWidget::endDate()const {
00249     return end;
00250 }
00251 void ORecurranceWidget::slotSetRType(int rtype) {
00252    // now call the right function based on the type...
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     // if the item was toggled, then go ahead and set it to the maximum date
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     // change the spelling based on the value of x
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     // don't do something we'll regret!!!
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     // a crazy check, if you are repeating weekly, the current day
00353     // must be selected!!!
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     // we need to make this unintrusive as possible...
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 // reshow the buttons...
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     // I hope clustering these improve performance....
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     // might as well set the day too...
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       // hide the extra buttons...
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     // figure out the week...
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     // I hope this works in other languages besides english...
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 }
KDE Logo
This file is part of the documentation for OPIE Version 1.1.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:45 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001