00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00123 int weekStart=KGlobal::locale()->weekStartDay();
00124 for ( int i = 0; i < 7; ++i ) {
00125
00126
00127
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
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)
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
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
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
00764
00765
00766
00767 mDateTimeLabel = new QLabel( mTimeGroupBox );
00768
00769
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
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
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
00957
00958
00959 recurrenceType = RecurrenceChooser::Monthly;
00960
00961 rmp = r->monthPositions();
00962 if ( rmp.first()->negative )
00963 count=-rmp.first()->rPos;
00964 else
00965
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
00979
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
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
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
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 }