korganizer Library API Documentation

koeditorrecurrence.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2000-2003 Cornelius Schumacher <schumacher@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qtooltip.h>
00025 #include <qfiledialog.h>
00026 #include <qlayout.h>
00027 #include <qvbox.h>
00028 #include <qbuttongroup.h>
00029 #include <qvgroupbox.h>
00030 #include <qwidgetstack.h>
00031 #include <qdatetime.h>
00032 #include <qlistbox.h>
00033 #include <qspinbox.h>
00034 #include <qcheckbox.h>
00035 
00036 #include <kdialog.h>
00037 #include <kglobal.h>
00038 #include <klocale.h>
00039 #include <kiconloader.h>
00040 #include <kdebug.h>
00041 #include <knumvalidator.h>
00042 #include <kcalendarsystem.h>
00043 
00044 #include <libkcal/event.h>
00045 
00046 #include <libkdepim/kdateedit.h>
00047 
00048 #include "koprefs.h"
00049 #include "koglobals.h"
00050 
00051 #include "koeditorrecurrence.h"
00052 #include "koeditorrecurrence.moc"
00053 
00055 
00056 RecurBase::RecurBase( QWidget *parent, const char *name ) :
00057   QWidget( parent, name )
00058 {
00059   mFrequencyEdit = new QSpinBox( 1, 9999, 1, this );
00060   mFrequencyEdit->setValue( 1 );
00061 }
00062 
00063 QWidget *RecurBase::frequencyEdit()
00064 {
00065   return mFrequencyEdit;
00066 }
00067 
00068 void RecurBase::setFrequency( int f )
00069 {
00070   if ( f < 1 ) f = 1;
00071 
00072   mFrequencyEdit->setValue( f );
00073 }
00074 
00075 int RecurBase::frequency()
00076 {
00077   return mFrequencyEdit->value();
00078 }
00079 
00081 
00082 RecurDaily::RecurDaily( QWidget *parent, const char *name ) :
00083   RecurBase( parent, name )
00084 {
00085   QBoxLayout *topLayout = new QHBoxLayout( this );
00086   topLayout->setSpacing( KDialog::spacingHint() );
00087 
00088   QLabel *preLabel = new QLabel( i18n("&Recur every"), this );
00089   topLayout->addWidget( preLabel );
00090 
00091   topLayout->addWidget( frequencyEdit() );
00092   preLabel->setBuddy( frequencyEdit() );
00093 
00094   QLabel *postLabel = new QLabel( i18n("day(s)"), this );
00095   topLayout->addWidget( postLabel );
00096 }
00097 
00098 
00100 
00101 RecurWeekly::RecurWeekly( QWidget *parent, const char *name ) :
00102   RecurBase( parent, name )
00103 {
00104   QBoxLayout *topLayout = new QVBoxLayout( this );
00105   topLayout->setSpacing( KDialog::spacingHint() );
00106 
00107   topLayout->addStretch( 1 );
00108 
00109   QBoxLayout *weeksLayout = new QHBoxLayout( topLayout );
00110 
00111   QLabel *preLabel = new QLabel( i18n("&Recur every"), this );
00112   weeksLayout->addWidget( preLabel );
00113 
00114   weeksLayout->addWidget( frequencyEdit() );
00115   preLabel->setBuddy( frequencyEdit() );
00116 
00117   QLabel *postLabel = new QLabel( i18n("week(s) on:"), this );
00118   weeksLayout->addWidget( postLabel );
00119 
00120   QHBox *dayBox = new QHBox( this );
00121   topLayout->addWidget( dayBox, 1, AlignVCenter );
00122   // Respect start of week setting
00123   int weekStart=KGlobal::locale()->weekStartDay();
00124   for ( int i = 0; i < 7; ++i ) {
00125     // i is the nr of the combobox, not the day of week!
00126     // label=(i+weekStart+6)%7 + 1;
00127     // index in CheckBox array(=day): label-1
00128     const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00129     QString weekDayName = calSys->weekDayName(
00130       (i + weekStart + 6)%7 + 1, true );
00131     if ( KOPrefs::instance()->mCompactDialogs ) {
00132       weekDayName = weekDayName.left( 1 );
00133     }
00134     mDayBoxes[ (i + weekStart + 6)%7 ] = new QCheckBox( weekDayName, dayBox );
00135   }
00136 
00137   topLayout->addStretch( 1 );
00138 }
00139 
00140 void RecurWeekly::setDays( const QBitArray &days )
00141 {
00142   for ( int i = 0; i < 7; ++i ) {
00143     mDayBoxes[ i ]->setChecked( days.testBit( i ) );
00144   }
00145 }
00146 
00147 QBitArray RecurWeekly::days()
00148 {
00149   QBitArray days( 7 );
00150 
00151   for ( int i = 0; i < 7; ++i ) {
00152     days.setBit( i, mDayBoxes[ i ]->isChecked() );
00153   }
00154 
00155   return days;
00156 }
00157 
00159 
00160 RecurMonthly::RecurMonthly( QWidget *parent, const char *name ) :
00161   RecurBase( parent, name )
00162 {
00163   QBoxLayout *topLayout = new QVBoxLayout( this );
00164   topLayout->setSpacing( KDialog::spacingHint() );
00165 
00166 
00167   QBoxLayout *freqLayout = new QHBoxLayout( topLayout );
00168 
00169   QLabel *preLabel = new QLabel( i18n("every"), this );
00170   freqLayout->addWidget( preLabel );
00171 
00172   freqLayout->addWidget( frequencyEdit() );
00173   preLabel->setBuddy( frequencyEdit() );
00174 
00175   QLabel *postLabel = new QLabel( i18n("month(s)"), this );
00176   freqLayout->addWidget( postLabel );
00177 
00178 
00179   QButtonGroup *buttonGroup = new QButtonGroup( this );
00180   buttonGroup->setFrameStyle( QFrame::NoFrame );
00181   topLayout->addWidget( buttonGroup, 1, AlignVCenter );
00182 
00183   QGridLayout *buttonLayout = new QGridLayout( buttonGroup, 3, 2 );
00184   buttonLayout->setSpacing( KDialog::spacingHint() );
00185 
00186 
00187   QString recurOnText;
00188   if ( !KOPrefs::instance()->mCompactDialogs ) {
00189     recurOnText = i18n("&Recur on the");
00190   }
00191 
00192   mByDayRadio = new QRadioButton( recurOnText, buttonGroup );
00193   buttonLayout->addWidget( mByDayRadio, 0, 0 );
00194 
00195   mByDayCombo = new QComboBox( buttonGroup );
00196   mByDayCombo->setSizeLimit( 7 );
00197   mByDayCombo->insertItem( i18n("1st") );
00198   mByDayCombo->insertItem( i18n("2nd") );
00199   mByDayCombo->insertItem( i18n("3rd") );
00200   mByDayCombo->insertItem( i18n("4th") );
00201   mByDayCombo->insertItem( i18n("5th") );
00202   mByDayCombo->insertItem( i18n("6th") );
00203   mByDayCombo->insertItem( i18n("7th") );
00204   mByDayCombo->insertItem( i18n("8th") );
00205   mByDayCombo->insertItem( i18n("9th") );
00206   mByDayCombo->insertItem( i18n("10th") );
00207   mByDayCombo->insertItem( i18n("11th") );
00208   mByDayCombo->insertItem( i18n("12th") );
00209   mByDayCombo->insertItem( i18n("13th") );
00210   mByDayCombo->insertItem( i18n("14th") );
00211   mByDayCombo->insertItem( i18n("15th") );
00212   mByDayCombo->insertItem( i18n("16th") );
00213   mByDayCombo->insertItem( i18n("17th") );
00214   mByDayCombo->insertItem( i18n("18th") );
00215   mByDayCombo->insertItem( i18n("19th") );
00216   mByDayCombo->insertItem( i18n("20th") );
00217   mByDayCombo->insertItem( i18n("21st") );
00218   mByDayCombo->insertItem( i18n("22nd") );
00219   mByDayCombo->insertItem( i18n("23rd") );
00220   mByDayCombo->insertItem( i18n("24th") );
00221   mByDayCombo->insertItem( i18n("25th") );
00222   mByDayCombo->insertItem( i18n("26th") );
00223   mByDayCombo->insertItem( i18n("27th") );
00224   mByDayCombo->insertItem( i18n("28th") );
00225   mByDayCombo->insertItem( i18n("29th") );
00226   mByDayCombo->insertItem( i18n("30th") );
00227   mByDayCombo->insertItem( i18n("31st") );
00228   buttonLayout->addWidget( mByDayCombo, 0, 1 );
00229 
00230   QLabel *byDayLabel = new QLabel( i18n("day"), buttonGroup );
00231   buttonLayout->addWidget( byDayLabel, 0, 2 );
00232 
00233 
00234   mByPosRadio = new QRadioButton( recurOnText, buttonGroup);
00235   buttonLayout->addWidget( mByPosRadio, 1, 0 );
00236 
00237   mByPosCountCombo = new QComboBox( buttonGroup );
00238   mByPosCountCombo->insertItem( i18n("1st") );
00239   mByPosCountCombo->insertItem( i18n("2nd") );
00240   mByPosCountCombo->insertItem( i18n("3rd") );
00241   mByPosCountCombo->insertItem( i18n("4th") );
00242   mByPosCountCombo->insertItem( i18n("5th") );
00243   mByPosCountCombo->insertItem( i18n("Last") );
00244   mByPosCountCombo->insertItem( i18n("2nd Last") );
00245   mByPosCountCombo->insertItem( i18n("3rd Last") );
00246   mByPosCountCombo->insertItem( i18n("4th Last") );
00247   mByPosCountCombo->insertItem( i18n("5th Last") );
00248 
00249   buttonLayout->addWidget( mByPosCountCombo, 1, 1 );
00250 
00251   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00252   mByPosWeekdayCombo = new QComboBox( buttonGroup );
00253   for( int i = 1; i <= 7; ++i ) {
00254     mByPosWeekdayCombo->insertItem( calSys->weekDayName( i ) );
00255   }
00256   buttonLayout->addWidget( mByPosWeekdayCombo, 1, 2 );
00257 }
00258 
00259 void RecurMonthly::setByDay( int day )
00260 {
00261   mByDayRadio->setChecked( true );
00262   mByDayCombo->setCurrentItem( day-1 );
00263 }
00264 
00265 void RecurMonthly::setByPos( int count, int weekday )
00266 {
00267   mByPosRadio->setChecked( true );
00268   if (count>0)
00269     mByPosCountCombo->setCurrentItem( count - 1 );
00270   else
00271     // negative weeks means counted from the end of month
00272     mByPosCountCombo->setCurrentItem( -count + 4 );
00273   mByPosWeekdayCombo->setCurrentItem( weekday );
00274 }
00275 
00276 bool RecurMonthly::byDay()
00277 {
00278   return mByDayRadio->isChecked();
00279 }
00280 
00281 bool RecurMonthly::byPos()
00282 {
00283   return mByPosRadio->isChecked();
00284 }
00285 
00286 int RecurMonthly::day()
00287 {
00288   return mByDayCombo->currentItem() + 1;
00289 }
00290 
00291 int RecurMonthly::count()
00292 {
00293   int pos=mByPosCountCombo->currentItem();
00294   if (pos<=4) // positive  count
00295     return pos+1;
00296   else
00297     return -pos+4;
00298 }
00299 
00300 int RecurMonthly::weekday()
00301 {
00302   return mByPosWeekdayCombo->currentItem();
00303 }
00304 
00306 
00307 RecurYearly::RecurYearly( QWidget *parent, const char *name ) :
00308   RecurBase( parent, name )
00309 {
00310   QBoxLayout *topLayout = new QVBoxLayout( this );
00311   topLayout->setSpacing( KDialog::spacingHint() );
00312 
00313 
00314   QBoxLayout *freqLayout = new QHBoxLayout( topLayout );
00315 
00316   QLabel *preLabel = new QLabel( i18n("&every"), this );
00317   freqLayout->addWidget( preLabel );
00318 
00319   freqLayout->addWidget( frequencyEdit() );
00320   preLabel->setBuddy( frequencyEdit() );
00321 
00322   QLabel *postLabel = new QLabel( i18n("year(s)"), this );
00323   freqLayout->addWidget( postLabel );
00324 
00325 
00326   QButtonGroup *buttonGroup = new QButtonGroup( this );
00327   buttonGroup->setFrameStyle( QFrame::NoFrame );
00328   topLayout->addWidget( buttonGroup, 1, AlignVCenter );
00329 
00330   QGridLayout *buttonLayout = new QGridLayout( buttonGroup, 3, 2 );
00331 
00332   QString recurInMonthText;
00333   if ( !KOPrefs::instance()->mCompactDialogs ) {
00334     recurInMonthText = i18n("&Recur in the month of");
00335   }
00336 
00337   mByMonthRadio = new QRadioButton( recurInMonthText, buttonGroup);
00338   buttonLayout->addWidget( mByMonthRadio, 0, 0 );
00339 
00340   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00341   mByMonthCombo = new QComboBox( buttonGroup );
00342   for( int i = 1; i <= 12; ++i ) {
00343     // use an arbitrary year, we just need the month name...
00344     QDate dt( 2005, i, 1 );
00345     mByMonthCombo->insertItem( calSys->monthName( dt ) );
00346   }
00347   buttonLayout->addWidget( mByMonthCombo, 0, 1 );
00348 
00349 
00350   buttonLayout->setRowStretch( 1, 1 );
00351 
00352   QString recurOnDayText;
00353   if ( KOPrefs::instance()->mCompactDialogs ) {
00354     recurOnDayText = i18n("This day");
00355   } else {
00356     recurOnDayText = i18n("Recur on this &day");
00357   }
00358 
00359   mByDayRadio = new QRadioButton( recurOnDayText, buttonGroup);
00360   buttonLayout->addMultiCellWidget( mByDayRadio, 2, 2, 0, 1 );
00361 }
00362 
00363 void RecurYearly::setDateTimes( QDateTime start, QDateTime ) 
00364 {
00365   QString recurOnDayText;
00366   if ( KOPrefs::instance()->mCompactDialogs ) {
00367     mByDayRadio->setText( i18n("This day") );
00368   } else {
00369     mByDayRadio->setText( i18n("Recur on &day %1 of the year").
00370         arg( start.date().dayOfYear() ) );
00371   }
00372 //  mByMonthCombo->setCurrentItem( start.date().month() + 1 );  
00373   if ( !KOPrefs::instance()->mCompactDialogs ) {
00374     mByMonthRadio->setText( i18n("&Recur on day %1 of ").arg( start.date().day() ) );
00375   }
00376 }
00377 
00378 void RecurYearly::setByDay()
00379 {
00380   mByDayRadio->setChecked( true );
00381 }
00382 
00383 void RecurYearly::setByMonth( int month )
00384 {
00385   mByMonthRadio->setChecked( true );
00386   mByMonthCombo->setCurrentItem( month - 1 );
00387 }
00388 
00389 bool RecurYearly::byMonth()
00390 {
00391   return mByMonthRadio->isChecked();
00392 }
00393 
00394 bool RecurYearly::byDay()
00395 {
00396   return mByDayRadio->isChecked();
00397 }
00398 
00399 int RecurYearly::month()
00400 {
00401   return mByMonthCombo->currentItem() + 1;
00402 }
00403 
00405 
00406 ExceptionsWidget::ExceptionsWidget( QWidget *parent, const char *name ) :
00407   QWidget( parent, name )
00408 {
00409   QBoxLayout *topLayout = new QVBoxLayout( this );
00410 
00411   QGroupBox *groupBox = new QGroupBox( 1, Horizontal, i18n("E&xceptions"),
00412                                        this );
00413   topLayout->addWidget( groupBox );
00414 
00415   QWidget *box = new QWidget( groupBox );
00416 
00417   QGridLayout *boxLayout = new QGridLayout( box );
00418 
00419   mExceptionDateEdit = new KDateEdit( box );
00420   mExceptionDateEdit->setDate( QDate::currentDate() );
00421   boxLayout->addWidget( mExceptionDateEdit, 0, 0 );
00422 
00423   QPushButton *addExceptionButton = new QPushButton( i18n("&Add"), box );
00424   boxLayout->addWidget( addExceptionButton, 1, 0 );
00425   QPushButton *changeExceptionButton = new QPushButton( i18n("&Change"), box );
00426   boxLayout->addWidget( changeExceptionButton, 2, 0 );
00427   QPushButton *deleteExceptionButton = new QPushButton( i18n("&Delete"), box );
00428   boxLayout->addWidget( deleteExceptionButton, 3, 0 );
00429 
00430   mExceptionList = new QListBox( box );
00431   boxLayout->addMultiCellWidget( mExceptionList, 0, 3, 1, 1 );
00432 
00433   boxLayout->setRowStretch( 4, 1 );
00434   boxLayout->setColStretch( 1, 3 );
00435 
00436   connect( addExceptionButton, SIGNAL( clicked() ),
00437            SLOT( addException() ) );
00438   connect( changeExceptionButton, SIGNAL( clicked() ),
00439            SLOT( changeException() ) );
00440   connect( deleteExceptionButton, SIGNAL( clicked() ),
00441            SLOT( deleteException() ) );
00442 }
00443 
00444 void ExceptionsWidget::addException()
00445 {
00446   QDate date = mExceptionDateEdit->date();
00447   QString dateStr = KGlobal::locale()->formatDate( date );
00448   if( !mExceptionList->findItem( dateStr ) ) {
00449     mExceptionDates.append( date );
00450     mExceptionList->insertItem( dateStr );
00451   }
00452 }
00453 
00454 void ExceptionsWidget::changeException()
00455 {
00456   int pos = mExceptionList->currentItem();
00457   if ( pos < 0 ) return;
00458 
00459   QDate date = mExceptionDateEdit->date();
00460   mExceptionDates[ pos ] = date;
00461   mExceptionList->changeItem( KGlobal::locale()->formatDate( date ), pos );
00462 }
00463 
00464 void ExceptionsWidget::deleteException()
00465 {
00466   int pos = mExceptionList->currentItem();
00467   if ( pos < 0 ) return;
00468 
00469   mExceptionDates.remove( mExceptionDates.at( pos ) );
00470   mExceptionList->removeItem( pos );
00471 }
00472 
00473 void ExceptionsWidget::setDates( const DateList &dates )
00474 {
00475   mExceptionList->clear();
00476   mExceptionDates.clear();
00477   DateList::ConstIterator dit;
00478   for ( dit = dates.begin(); dit != dates.end(); ++dit ) {
00479     mExceptionList->insertItem( KGlobal::locale()->formatDate(* dit ) );
00480     mExceptionDates.append( *dit );
00481   }
00482 }
00483 
00484 DateList ExceptionsWidget::dates()
00485 {
00486   return mExceptionDates;
00487 }
00488 
00490 
00491 ExceptionsDialog::ExceptionsDialog( QWidget *parent, const char *name ) :
00492   KDialogBase( parent, name, true, i18n("Edit Exceptions"), Ok|Cancel )
00493 {
00494   mExceptions = new ExceptionsWidget( this );
00495   setMainWidget( mExceptions );
00496 }
00497 
00498 void ExceptionsDialog::setDates( const DateList &dates )
00499 {
00500   mExceptions->setDates( dates );
00501 }
00502 
00503 DateList ExceptionsDialog::dates()
00504 {
00505   return mExceptions->dates();
00506 }
00507 
00509 
00510 RecurrenceRangeWidget::RecurrenceRangeWidget( QWidget *parent,
00511                                               const char *name )
00512   : QWidget( parent, name )
00513 {
00514   QBoxLayout *topLayout = new QVBoxLayout( this );
00515 
00516   mRangeGroupBox = new QGroupBox( 1, Horizontal, i18n("Recurrence Range"),
00517                                   this );
00518   topLayout->addWidget( mRangeGroupBox );
00519 
00520   QWidget *rangeBox = new QWidget( mRangeGroupBox );
00521   QVBoxLayout *rangeLayout = new QVBoxLayout( rangeBox );
00522   rangeLayout->setSpacing( KDialog::spacingHint() );
00523 
00524   mStartDateLabel = new QLabel( i18n("Begin on:"), rangeBox );
00525   rangeLayout->addWidget( mStartDateLabel );
00526 
00527   QButtonGroup *rangeButtonGroup = new QButtonGroup;
00528 
00529   mNoEndDateButton = new QRadioButton( i18n("&No ending date"), rangeBox );
00530   rangeButtonGroup->insert( mNoEndDateButton );
00531   rangeLayout->addWidget( mNoEndDateButton );
00532 
00533   QBoxLayout *durationLayout = new QHBoxLayout( rangeLayout );
00534   durationLayout->setSpacing( KDialog::spacingHint() );
00535 
00536   mEndDurationButton = new QRadioButton( i18n("End &after"), rangeBox );
00537   rangeButtonGroup->insert( mEndDurationButton );
00538   durationLayout->addWidget( mEndDurationButton );
00539 
00540   mEndDurationEdit = new QSpinBox( 1, 9999, 1, rangeBox );
00541   durationLayout->addWidget( mEndDurationEdit );
00542 
00543   QLabel *endDurationLabel = new QLabel( i18n("&occurrence(s)"), rangeBox );
00544   durationLayout ->addWidget( endDurationLabel );
00545   endDurationLabel->setBuddy( mEndDurationEdit );
00546 
00547   QBoxLayout *endDateLayout = new QHBoxLayout( rangeLayout );
00548   endDateLayout->setSpacing( KDialog::spacingHint() );
00549 
00550   mEndDateButton = new QRadioButton( i18n("End &by:"), rangeBox );
00551   rangeButtonGroup->insert( mEndDateButton );
00552   endDateLayout->addWidget( mEndDateButton );
00553 
00554   mEndDateEdit = new KDateEdit( rangeBox );
00555   endDateLayout->addWidget( mEndDateEdit );
00556 
00557   endDateLayout->addStretch( 1 );
00558 
00559   connect( mNoEndDateButton, SIGNAL( toggled( bool ) ),
00560            SLOT( showCurrentRange() ) );
00561   connect( mEndDurationButton, SIGNAL( toggled( bool ) ),
00562            SLOT( showCurrentRange() ) );
00563   connect( mEndDateButton, SIGNAL( toggled( bool ) ),
00564            SLOT( showCurrentRange() ) );
00565 }
00566 
00567 void RecurrenceRangeWidget::setDefaults( const QDateTime &from  )
00568 {
00569   mNoEndDateButton->setChecked( true );
00570 
00571   setDateTimes( from );
00572 }
00573 
00574 void RecurrenceRangeWidget::setDuration( int duration )
00575 {
00576   if ( duration == -1 ) {
00577     mNoEndDateButton->setChecked( true );
00578   } else if ( duration == 0 ) {
00579     mEndDateButton->setChecked( true );
00580   } else {
00581     mEndDurationButton->setChecked( true );
00582     mEndDurationEdit->setValue( duration );
00583   }
00584 }
00585 
00586 int RecurrenceRangeWidget::duration()
00587 {
00588   if ( mNoEndDateButton->isChecked() ) {
00589     return -1;
00590   } else if ( mEndDurationButton->isChecked() ) {
00591     return mEndDurationEdit->value();
00592   } else {
00593     return 0;
00594   }
00595 }
00596 
00597 void RecurrenceRangeWidget::setEndDate( const QDate &date )
00598 {
00599   mEndDateEdit->setDate( date );
00600 }
00601 
00602 QDate RecurrenceRangeWidget::endDate()
00603 {
00604   return mEndDateEdit->date();
00605 }
00606 
00607 void RecurrenceRangeWidget::showCurrentRange()
00608 {
00609   mEndDurationEdit->setEnabled( mEndDurationButton->isChecked() );
00610   mEndDateEdit->setEnabled( mEndDateButton->isChecked() );
00611 }
00612 
00613 void RecurrenceRangeWidget::setDateTimes( const QDateTime &start,
00614                                           const QDateTime & )
00615 {
00616   mStartDateLabel->setText( i18n("Begins on: %1")
00617       .arg( KGlobal::locale()->formatDate( start.date() ) ) );
00618 }
00619 
00621 
00622 RecurrenceRangeDialog::RecurrenceRangeDialog( QWidget *parent,
00623                                               const char *name ) :
00624   KDialogBase( parent, name, true, i18n("Edit Recurrence Range"), Ok|Cancel )
00625 {
00626   mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
00627   setMainWidget( mRecurrenceRangeWidget );
00628 }
00629 
00630 void RecurrenceRangeDialog::setDefaults( const QDateTime &from )
00631 {
00632   mRecurrenceRangeWidget->setDefaults( from );
00633 }
00634 
00635 void RecurrenceRangeDialog::setDuration( int duration )
00636 {
00637   mRecurrenceRangeWidget->setDuration( duration );
00638 }
00639 
00640 int RecurrenceRangeDialog::duration()
00641 {
00642   return mRecurrenceRangeWidget->duration();
00643 }
00644 
00645 void RecurrenceRangeDialog::setEndDate( const QDate &date )
00646 {
00647   mRecurrenceRangeWidget->setEndDate( date );
00648 }
00649 
00650 QDate RecurrenceRangeDialog::endDate()
00651 {
00652   return mRecurrenceRangeWidget->endDate();
00653 }
00654 
00655 void RecurrenceRangeDialog::setDateTimes( const QDateTime &start,
00656                                           const QDateTime &end )
00657 {
00658   mRecurrenceRangeWidget->setDateTimes( start, end );
00659 }
00660 
00662 
00663 RecurrenceChooser::RecurrenceChooser( QWidget *parent, const char *name ) :
00664   QWidget( parent, name )
00665 {
00666   QBoxLayout *topLayout = new QVBoxLayout( this );
00667 
00668   if ( KOPrefs::instance()->mCompactDialogs ) {
00669     mTypeCombo = new QComboBox( this );
00670     mTypeCombo->insertItem( i18n("Daily") );
00671     mTypeCombo->insertItem( i18n("Weekly") );
00672     mTypeCombo->insertItem( i18n("Monthly") );
00673     mTypeCombo->insertItem( i18n("Yearly") );
00674 
00675     topLayout->addWidget( mTypeCombo );
00676 
00677     connect( mTypeCombo, SIGNAL( activated( int ) ), SLOT( emitChoice() ) );
00678   } else {
00679     mTypeCombo = 0;
00680 
00681     QButtonGroup *ruleButtonGroup = new QButtonGroup( 1, Horizontal, this );
00682     ruleButtonGroup->setFrameStyle( QFrame::NoFrame );
00683     topLayout->addWidget( ruleButtonGroup );
00684 
00685     mDailyButton = new QRadioButton( i18n("&Daily"), ruleButtonGroup );
00686     mWeeklyButton = new QRadioButton( i18n("&Weekly"), ruleButtonGroup );
00687     mMonthlyButton = new QRadioButton( i18n("&Monthly"), ruleButtonGroup );
00688     mYearlyButton = new QRadioButton( i18n("&Yearly"), ruleButtonGroup );
00689 
00690     connect( mDailyButton, SIGNAL( toggled( bool ) ),
00691              SLOT( emitChoice() ) );
00692     connect( mWeeklyButton, SIGNAL( toggled( bool ) ),
00693              SLOT( emitChoice() ) );
00694     connect( mMonthlyButton, SIGNAL( toggled( bool ) ),
00695              SLOT( emitChoice() ) );
00696     connect( mYearlyButton, SIGNAL( toggled( bool ) ),
00697              SLOT( emitChoice() ) );
00698   }
00699 }
00700 
00701 int RecurrenceChooser::type()
00702 {
00703   if ( mTypeCombo ) {
00704     return mTypeCombo->currentItem();
00705   } else {
00706     if ( mDailyButton->isChecked() ) return Daily;
00707     else if ( mWeeklyButton->isChecked() ) return Weekly;
00708     else if ( mMonthlyButton->isChecked() ) return Monthly;
00709     else return Yearly;
00710   }
00711 }
00712 
00713 void RecurrenceChooser::setType( int type )
00714 {
00715   if ( mTypeCombo ) {
00716     mTypeCombo->setCurrentItem( type );
00717   } else {
00718     switch ( type ) {
00719       case Daily:
00720         mDailyButton->setChecked( true );
00721         break;
00722       case Weekly:
00723         mWeeklyButton->setChecked( true );
00724         break;
00725       case Monthly:
00726         mMonthlyButton->setChecked( true );
00727         break;
00728       case Yearly:
00729       default:
00730         mYearlyButton->setChecked( true );
00731         break;
00732     }
00733   }
00734 }
00735 
00736 void RecurrenceChooser::emitChoice()
00737 {
00738   emit chosen ( type() );
00739 }
00740 
00742 
00743 KOEditorRecurrence::KOEditorRecurrence( QWidget* parent, const char *name ) :
00744   QWidget( parent, name )
00745 {
00746   QGridLayout *topLayout = new QGridLayout( this );
00747   topLayout->setSpacing( KDialog::spacingHint() );
00748 
00749   mEnabledCheck = new QCheckBox( i18n("&Enable recurrence"), this );
00750   connect( mEnabledCheck, SIGNAL( toggled( bool ) ),
00751            SLOT( setEnabled( bool ) ) );
00752   topLayout->addMultiCellWidget( mEnabledCheck, 0, 0, 0, 1 );
00753 
00754 
00755   mTimeGroupBox = new QGroupBox( 1, Horizontal, i18n("Appointment Time "),
00756                                  this );
00757   topLayout->addMultiCellWidget( mTimeGroupBox, 1, 1 , 0 , 1 );
00758 
00759   if ( KOPrefs::instance()->mCompactDialogs ) {
00760     mTimeGroupBox->hide();
00761   }
00762 
00763 //  QFrame *timeFrame = new QFrame( mTimeGroupBox );
00764 //  QBoxLayout *layoutTimeFrame = new QHBoxLayout( timeFrame );
00765 //  layoutTimeFrame->setSpacing( KDialog::spacingHint() );
00766 
00767   mDateTimeLabel = new QLabel( mTimeGroupBox );
00768 //  mDateTimeLabel = new QLabel( timeFrame );
00769 //  layoutTimeFrame->addWidget( mDateTimeLabel );
00770 
00771   Qt::Orientation orientation;
00772   if ( KOPrefs::instance()->mCompactDialogs ) orientation = Horizontal;
00773   else orientation = Vertical;
00774 
00775   mRuleBox = new QGroupBox( 1, orientation, i18n("Recurrence Rule"), this );
00776   if ( KOPrefs::instance()->mCompactDialogs ) {
00777     topLayout->addWidget( mRuleBox, 2, 0 );
00778   } else {
00779     topLayout->addMultiCellWidget( mRuleBox, 2, 2, 0, 1 );
00780   }
00781 
00782   mRecurrenceChooser = new RecurrenceChooser( mRuleBox );
00783   connect( mRecurrenceChooser, SIGNAL( chosen( int ) ),
00784            SLOT( showCurrentRule( int ) ) );
00785 
00786   if ( !KOPrefs::instance()->mCompactDialogs ) {
00787     QFrame *ruleSepFrame = new QFrame( mRuleBox );
00788     ruleSepFrame->setFrameStyle( QFrame::VLine | QFrame::Sunken );
00789   }
00790 
00791   mRuleStack = new QWidgetStack( mRuleBox );
00792 
00793   mDaily = new RecurDaily( mRuleStack );
00794   mRuleStack->addWidget( mDaily, 0 );
00795 
00796   mWeekly = new RecurWeekly( mRuleStack );
00797   mRuleStack->addWidget( mWeekly, 0 );
00798 
00799   mMonthly = new RecurMonthly( mRuleStack );
00800   mRuleStack->addWidget( mMonthly, 0 );
00801 
00802   mYearly = new RecurYearly( mRuleStack );
00803   mRuleStack->addWidget( mYearly, 0 );
00804 
00805   showCurrentRule( mRecurrenceChooser->type() );
00806 
00807   if ( KOPrefs::instance()->mCompactDialogs ) {
00808     mRecurrenceRangeWidget = 0;
00809     mRecurrenceRangeDialog = new RecurrenceRangeDialog( this );
00810     mRecurrenceRange = mRecurrenceRangeDialog;
00811     mRecurrenceRangeButton = new QPushButton( i18n("Recurrence Range..."),
00812                                               this );
00813     topLayout->addWidget( mRecurrenceRangeButton, 3, 0 );
00814     connect( mRecurrenceRangeButton, SIGNAL( clicked() ),
00815              SLOT( showRecurrenceRangeDialog() ) );
00816 
00817     mExceptionsWidget = 0;
00818     mExceptionsDialog = new ExceptionsDialog( this );
00819     mExceptions = mExceptionsDialog;
00820     mExceptionsButton = new QPushButton( i18n("Exceptions..."), this );
00821     topLayout->addWidget( mExceptionsButton, 4, 0 );
00822     connect( mExceptionsButton, SIGNAL( clicked() ),
00823              SLOT( showExceptionsDialog() ) );
00824 
00825   } else {
00826     mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
00827     mRecurrenceRangeDialog = 0;
00828     mRecurrenceRange = mRecurrenceRangeWidget;
00829     mRecurrenceRangeButton = 0;
00830     topLayout->addWidget( mRecurrenceRangeWidget, 3, 0 );
00831 
00832     mExceptionsWidget = new ExceptionsWidget( this );
00833     mExceptionsDialog = 0;
00834     mExceptions = mExceptionsWidget;
00835     mExceptionsButton = 0;
00836     topLayout->addWidget( mExceptionsWidget, 3, 1 );
00837   }
00838 }
00839 
00840 KOEditorRecurrence::~KOEditorRecurrence()
00841 {
00842 }
00843 
00844 void KOEditorRecurrence::setEnabled( bool enabled )
00845 {
00846 //  kdDebug(5850) << "KOEditorRecurrence::setEnabled(): " << (enabled ? "on" : "off") << endl;
00847 
00848   mTimeGroupBox->setEnabled( enabled );
00849   mRuleBox->setEnabled( enabled );
00850   if ( mRecurrenceRangeWidget ) mRecurrenceRangeWidget->setEnabled( enabled );
00851   if ( mRecurrenceRangeButton ) mRecurrenceRangeButton->setEnabled( enabled );
00852   if ( mExceptionsWidget ) mExceptionsWidget->setEnabled( enabled );
00853   if ( mExceptionsButton ) mExceptionsButton->setEnabled( enabled );
00854 }
00855 
00856 void KOEditorRecurrence::showCurrentRule( int current )
00857 {
00858   switch ( current ) {
00859     case Daily:
00860       mRuleStack->raiseWidget( mDaily );
00861       break;
00862     case Weekly:
00863       mRuleStack->raiseWidget( mWeekly );
00864       break;
00865     case Monthly:
00866       mRuleStack->raiseWidget( mMonthly );
00867       break;
00868     default:
00869     case Yearly:
00870       mRuleStack->raiseWidget( mYearly );
00871       break;
00872   }
00873 }
00874 
00875 void KOEditorRecurrence::setDateTimes( QDateTime start, QDateTime end )
00876 {
00877 //  kdDebug(5850) << "KOEditorRecurrence::setDateTimes" << endl;
00878 
00879   mRecurrenceRange->setDateTimes( start, end );
00880   mDaily->setDateTimes( start, end );
00881   mWeekly->setDateTimes( start, end );
00882   mMonthly->setDateTimes( start, end );
00883   mYearly->setDateTimes( start, end );
00884 }
00885 
00886 void KOEditorRecurrence::setDefaults( QDateTime from, QDateTime to, bool )
00887 {
00888   setDateTimes( from, to );
00889 
00890   bool enabled = false;
00891   mEnabledCheck->setChecked( enabled );
00892   setEnabled( enabled );
00893 
00894   mRecurrenceRange->setDefaults( from );
00895 
00896   mRecurrenceChooser->setType( RecurrenceChooser::Weekly );
00897   showCurrentRule( mRecurrenceChooser->type() );
00898 
00899   mDaily->setFrequency( 1 );
00900 
00901   mWeekly->setFrequency( 1 );
00902   QBitArray days( 7 );
00903   days.fill( 0 );
00904   days.setBit( (from.date().dayOfWeek()+6) % 7 );
00905   mWeekly->setDays( days );
00906 
00907   mMonthly->setFrequency( 1 );
00908   mMonthly->setByPos( from.date().day()/7 + 1, from.date().dayOfWeek() );
00909   mMonthly->setByDay( from.date().day() );
00910 
00911   mYearly->setFrequency( 1 );
00912   mYearly->setByMonth( from.date().month() );
00913 }
00914 
00915 void KOEditorRecurrence::readEvent(Event *event)
00916 {
00917   QBitArray rDays( 7 );
00918   QPtrList<Recurrence::rMonthPos> rmp;
00919   QPtrList<int> rmd;
00920   int day = 0;
00921   int count = 0;
00922   int month = 0;
00923   setDefaults( event->dtStart(), event->dtEnd(), event->doesFloat() );
00924 
00925   setDateTimes( event->dtStart(), event->dtEnd() );
00926 
00927   int recurs = event->doesRecur();
00928   int f = 0;
00929   Recurrence *r = 0;
00930 
00931   if ( recurs )
00932   {
00933     r = event->recurrence();
00934     f = r->frequency();
00935   }
00936 
00937 
00938   mEnabledCheck->setChecked( recurs );
00939   setEnabled( recurs );
00940 
00941   int recurrenceType = RecurrenceChooser::Weekly;
00942 
00943   switch ( recurs ) {
00944     case Recurrence::rNone:
00945       break;
00946     case Recurrence::rDaily:
00947       recurrenceType = RecurrenceChooser::Daily;
00948       mDaily->setFrequency( f );
00949       break;
00950     case Recurrence::rWeekly:
00951       recurrenceType = RecurrenceChooser::Weekly;
00952       mWeekly->setFrequency( f );
00953       mWeekly->setDays( r->days() );
00954       break;
00955     case Recurrence::rMonthlyPos:
00956       // we only handle one possibility in the list right now,
00957       // so I have hardcoded calls with first().  If we make the GUI
00958       // more extended, this can be changed.
00959       recurrenceType = RecurrenceChooser::Monthly;
00960 
00961       rmp = r->monthPositions();
00962       if ( rmp.first()->negative )
00963         count=-rmp.first()->rPos;
00964       else
00965         // give the week as -5 to -1 and 1 to 5. the widget will do the rest
00966         count = rmp.first()->rPos;
00967       day = 0;
00968       while ( !rmp.first()->rDays.testBit( day ) ) ++day;
00969       mMonthly->setByPos( count, day );
00970 
00971       mMonthly->setFrequency( f );
00972 
00973       break;
00974     case Recurrence::rMonthlyDay:
00975       recurrenceType = RecurrenceChooser::Monthly;
00976 
00977       rmd = r->monthDays();
00978       // check if we have any setting for which day (vcs import is broken and 
00979       // does not set any day, thus we need to check)
00980       if ( rmd.first() ) {
00981         day = *rmd.first();
00982       } else {
00983         day = event->dtStart().date().day();
00984       }
00985       mMonthly->setByDay( day );
00986 
00987       mMonthly->setFrequency( f );
00988 
00989       break;
00990     case Recurrence::rYearlyMonth:
00991     case Recurrence::rYearlyDay:
00992       recurrenceType = RecurrenceChooser::Yearly;
00993 
00994       rmd = r->yearNums();
00995       month = *rmd.first();
00996       if ( month == event->dtStart().date().month() ) {
00997         mYearly->setByDay();
00998       } else {
00999         mYearly->setByMonth( month );
01000       }
01001 
01002       mYearly->setFrequency( f );
01003       break;
01004     default:
01005       break;
01006   }
01007 
01008   mRecurrenceChooser->setType( recurrenceType );
01009   showCurrentRule( recurrenceType );
01010 
01011   mRecurrenceRange->setDateTimes( event->dtStart() );
01012 
01013   if ( event->doesRecur() ) {
01014     mRecurrenceRange->setDuration( r->duration() );
01015     if ( r->duration() == 0 ) mRecurrenceRange->setEndDate( r->endDate() );
01016   }
01017 
01018   mExceptions->setDates( event->exDates() );
01019 }
01020 
01021 void KOEditorRecurrence::writeEvent( Event *event )
01022 {
01023   if ( !mEnabledCheck->isChecked() )
01024   {
01025     if (event->doesRecur())
01026         event->recurrence()->unsetRecurs();
01027     return;
01028   }
01029 
01030   Recurrence *r = event->recurrence();
01031 
01032   // clear out any old settings;
01033   r->unsetRecurs();
01034 
01035   int duration = mRecurrenceRange->duration();
01036   QDate endDate;
01037   if ( duration == 0 ) endDate = mRecurrenceRange->endDate();
01038 
01039   int recurrenceType = mRecurrenceChooser->type();
01040 
01041   if ( recurrenceType == RecurrenceChooser::Daily ) {
01042       int freq = mDaily->frequency();
01043       if ( duration != 0 ) r->setDaily( freq, duration );
01044       else  r->setDaily( freq, endDate );
01045   } else if ( recurrenceType == RecurrenceChooser::Weekly ) {
01046       int freq = mWeekly->frequency();
01047       QBitArray days = mWeekly->days();
01048       if ( duration != 0 ) r->setWeekly( freq, days, duration );
01049       else r->setWeekly( freq, days, endDate );
01050   } else if ( recurrenceType == RecurrenceChooser::Monthly ) {
01051       int freq = mMonthly->frequency();
01052       if ( mMonthly->byPos() ) {
01053           int pos = mMonthly->count();
01054 
01055           QBitArray days( 7 );
01056           days.fill( false );
01057 
01058           days.setBit( mMonthly->weekday() );
01059           if ( duration != 0 )
01060               r->setMonthly( Recurrence::rMonthlyPos, freq, duration );
01061           else
01062               r->setMonthly( Recurrence::rMonthlyPos, freq, endDate );
01063           r->addMonthlyPos( pos, days );
01064       } else {
01065           // it's by day
01066           int day = mMonthly->day();
01067 
01068           if ( duration != 0 ) {
01069               r->setMonthly( Recurrence::rMonthlyDay, freq, duration );
01070           } else {
01071               r->setMonthly( Recurrence::rMonthlyDay, freq, endDate );
01072           }
01073           r->addMonthlyDay( day );
01074       }
01075   } else if ( recurrenceType == RecurrenceChooser::Yearly ) {
01076       int freq = mYearly->frequency();
01077 
01078       int month;
01079       if ( mYearly->byMonth() ) {
01080           month = mYearly->month();
01081       } else {
01082           month = event->dtStart().date().month();
01083       }
01084       if ( duration != 0 ) {
01085         r->setYearly( Recurrence::rYearlyMonth, freq, duration );
01086       } else {
01087         r->setYearly( Recurrence::rYearlyMonth, freq, endDate );
01088       }
01089 
01090       r->addYearlyNum( month );
01091     }
01092 
01093     event->setExDates( mExceptions->dates() );
01094 }
01095 
01096 void KOEditorRecurrence::setDateTimeStr( const QString &str )
01097 {
01098   mDateTimeLabel->setText( str );
01099 }
01100 
01101 bool KOEditorRecurrence::validateInput()
01102 {
01103   // Check input here
01104 
01105   return true;
01106 }
01107 
01108 void KOEditorRecurrence::showExceptionsDialog()
01109 {
01110   DateList dates = mExceptions->dates();
01111   int result = mExceptionsDialog->exec();
01112   if ( result == QDialog::Rejected ) mExceptions->setDates( dates );
01113 }
01114 
01115 void KOEditorRecurrence::showRecurrenceRangeDialog()
01116 {
01117   int duration = mRecurrenceRange->duration();
01118   QDate endDate = mRecurrenceRange->endDate();
01119 
01120   int result = mRecurrenceRangeDialog->exec();
01121   if ( result == QDialog::Rejected ) {
01122     mRecurrenceRange->setDuration( duration );
01123     mRecurrenceRange->setEndDate( endDate );
01124   }
01125 }
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:29 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003