korganizer

koeditorrecurrence.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2000-2003 Cornelius Schumacher <schumacher@kde.org>
00004     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of TQt, and distribute the resulting executable,
00022     without including the source code for TQt in the source distribution.
00023 */
00024 
00025 #include <tqtooltip.h>
00026 #include <tqfiledialog.h>
00027 #include <tqlayout.h>
00028 #include <tqvbox.h>
00029 #include <tqbuttongroup.h>
00030 #include <tqvgroupbox.h>
00031 #include <tqwidgetstack.h>
00032 #include <tqdatetime.h>
00033 #include <tqlistbox.h>
00034 #include <tqspinbox.h>
00035 #include <tqcheckbox.h>
00036 #include <tqgroupbox.h>
00037 #include <tqwidgetstack.h>
00038 #include <tqradiobutton.h>
00039 #include <tqlabel.h>
00040 #include <tqpushbutton.h>
00041 #include <tqwhatsthis.h>
00042 
00043 #include <kdialog.h>
00044 #include <tdeglobal.h>
00045 #include <tdelocale.h>
00046 #include <kiconloader.h>
00047 #include <kdebug.h>
00048 #include <knumvalidator.h>
00049 #include <kcalendarsystem.h>
00050 #include <tdemessagebox.h>
00051 
00052 #include <libtdepim/kdateedit.h>
00053 #include <libkcal/todo.h>
00054 
00055 #include "koprefs.h"
00056 #include "koglobals.h"
00057 
00058 #include "koeditorrecurrence.h"
00059 #include "koeditorrecurrence.moc"
00060 
00062 
00063 RecurBase::RecurBase( TQWidget *parent, const char *name ) :
00064   TQWidget( parent, name )
00065 {
00066   mFrequencyEdit = new TQSpinBox( 1, 9999, 1, this );
00067   mFrequencyEdit->setValue( 1 );
00068 }
00069 
00070 TQWidget *RecurBase::frequencyEdit()
00071 {
00072   return mFrequencyEdit;
00073 }
00074 
00075 void RecurBase::setFrequency( int f )
00076 {
00077   if ( f < 1 ) f = 1;
00078 
00079   mFrequencyEdit->setValue( f );
00080 }
00081 
00082 int RecurBase::frequency()
00083 {
00084   return mFrequencyEdit->value();
00085 }
00086 
00087 TQComboBox *RecurBase::createWeekCountCombo( TQWidget *parent, const char *name )
00088 {
00089   TQComboBox *combo = new TQComboBox( parent, name );
00090   TQWhatsThis::add( combo,
00091                    i18n("The number of the week from the beginning "
00092                         "of the month on which this event or to-do "
00093                         "should recur.") );
00094   if ( !combo ) return 0;
00095   combo->insertItem( i18n("1st") );
00096   combo->insertItem( i18n("2nd") );
00097   combo->insertItem( i18n("3rd") );
00098   combo->insertItem( i18n("4th") );
00099   combo->insertItem( i18n("5th") );
00100   combo->insertItem( i18n("Last") );
00101   combo->insertItem( i18n("2nd Last") );
00102   combo->insertItem( i18n("3rd Last") );
00103   combo->insertItem( i18n("4th Last") );
00104   combo->insertItem( i18n("5th Last") );
00105   return combo;
00106 }
00107 
00108 TQComboBox *RecurBase::createWeekdayCombo( TQWidget *parent, const char *name )
00109 {
00110   TQComboBox *combo = new TQComboBox( parent, name );
00111   TQWhatsThis::add( combo,
00112                    i18n("The weekday on which this event or to-do "
00113                         "should recur.") );
00114   if ( !combo ) return 0;
00115   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00116   for( int i = 1; i <= 7; ++i ) {
00117     combo->insertItem( calSys->weekDayName( i ) );
00118   }
00119   return combo;
00120 }
00121 
00122 TQComboBox *RecurBase::createMonthNameCombo( TQWidget *parent, const char *name )
00123 {
00124   TQComboBox *combo = new TQComboBox( parent, name );
00125   TQWhatsThis::add( combo,
00126                    i18n("The month during which this event or to-do "
00127                         "should recur.") );
00128   if ( !combo ) return 0;
00129   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00130   for( int i = 1; i <= 12; ++i ) {
00131     // use an arbitrary year, we just need the month name...
00132     TQDate dt( 2005, i, 1 );
00133     combo->insertItem( calSys->monthName( dt ) );
00134   }
00135   return combo;
00136 }
00137 
00138 TQBoxLayout *RecurBase::createFrequencySpinBar( TQWidget *parent, TQLayout *layout,
00139     TQString everyText, TQString unitText )
00140 {
00141   TQBoxLayout *freqLayout = new TQHBoxLayout( layout );
00142 
00143   TQString whatsThis = i18n("Sets how often this event or to-do should recur.");
00144   TQLabel *preLabel = new TQLabel( everyText, parent );
00145   TQWhatsThis::add( preLabel, whatsThis );
00146   freqLayout->addWidget( preLabel );
00147 
00148   freqLayout->addWidget( frequencyEdit() );
00149   preLabel->setBuddy( frequencyEdit() );
00150   TQWhatsThis::add( preLabel->buddy(), whatsThis );
00151 
00152   TQLabel *postLabel = new TQLabel( unitText, parent );
00153   TQWhatsThis::add( postLabel, whatsThis );
00154   freqLayout->addWidget( postLabel );
00155   freqLayout->addStretch();
00156   return freqLayout;
00157 }
00158 
00160 
00161 RecurDaily::RecurDaily( TQWidget *parent, const char *name ) :
00162   RecurBase( parent, name )
00163 {
00164   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00165   topLayout->setSpacing( KDialog::spacingHint() );
00166 
00167   createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("day(s)") );
00168 }
00169 
00170 
00172 
00173 RecurWeekly::RecurWeekly( TQWidget *parent, const char *name ) :
00174   RecurBase( parent, name )
00175 {
00176   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00177   topLayout->setSpacing( KDialog::spacingHint() );
00178 
00179 //  topLayout->addStretch( 1 );
00180 
00181   createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("week(s) on:") );
00182 
00183   TQHBox *dayBox = new TQHBox( this );
00184   topLayout->addWidget( dayBox, 1, AlignVCenter );
00185   // Respect start of week setting
00186   int weekStart=TDEGlobal::locale()->weekStartDay();
00187   for ( int i = 0; i < 7; ++i ) {
00188     // i is the nr of the combobox, not the day of week!
00189     // label=(i+weekStart+6)%7 + 1;
00190     // index in CheckBox array(=day): label-1
00191     const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00192     TQString weekDayName = calSys->weekDayName(
00193       (i + weekStart + 6)%7 + 1, true );
00194     if ( KOPrefs::instance()->mCompactDialogs ) {
00195       weekDayName = weekDayName.left( 1 );
00196     }
00197     mDayBoxes[ (i + weekStart + 6)%7 ] = new TQCheckBox( weekDayName, dayBox );
00198     TQWhatsThis::add( mDayBoxes[ (i + weekStart + 6)%7 ],
00199                      i18n("Day of the week on which this event or to-do "
00200                           "should recur.") );
00201   }
00202 
00203   topLayout->addStretch( 1 );
00204 }
00205 
00206 void RecurWeekly::setDays( const TQBitArray &days )
00207 {
00208   for ( int i = 0; i < 7; ++i ) {
00209     mDayBoxes[ i ]->setChecked( days.testBit( i ) );
00210   }
00211 }
00212 
00213 TQBitArray RecurWeekly::days()
00214 {
00215   TQBitArray days( 7 );
00216 
00217   for ( int i = 0; i < 7; ++i ) {
00218     days.setBit( i, mDayBoxes[ i ]->isChecked() );
00219   }
00220 
00221   return days;
00222 }
00223 
00225 
00226 RecurMonthly::RecurMonthly( TQWidget *parent, const char *name ) :
00227   RecurBase( parent, name )
00228 {
00229   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00230   topLayout->setSpacing( KDialog::spacingHint() );
00231 
00232   createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("month(s)") );
00233 
00234   TQButtonGroup *buttonGroup = new TQButtonGroup( this );
00235   buttonGroup->setFrameStyle( TQFrame::NoFrame );
00236   topLayout->addWidget( buttonGroup, 1, AlignVCenter );
00237 
00238   TQGridLayout *buttonLayout = new TQGridLayout( buttonGroup, 3, 2 );
00239   buttonLayout->setSpacing( KDialog::spacingHint() );
00240 
00241 
00242   TQString recurOnText;
00243   if ( !KOPrefs::instance()->mCompactDialogs ) {
00244     recurOnText = i18n("&Recur on the");
00245   }
00246 
00247   mByDayRadio = new TQRadioButton( recurOnText, buttonGroup );
00248   TQWhatsThis::add( mByDayRadio,
00249                    i18n("Sets a specific day of the month on which "
00250                         "this event or to-do should recur.") );
00251 
00252   buttonLayout->addWidget( mByDayRadio, 0, 0 );
00253 
00254   TQString whatsThis = i18n("The day of the month on which this event or to-do "
00255                            "should recur.");
00256   mByDayCombo = new TQComboBox( buttonGroup );
00257   TQWhatsThis::add( mByDayCombo, whatsThis );
00258   mByDayCombo->setSizeLimit( 7 );
00259   mByDayCombo->insertItem( i18n("1st") );
00260   mByDayCombo->insertItem( i18n("2nd") );
00261   mByDayCombo->insertItem( i18n("3rd") );
00262   mByDayCombo->insertItem( i18n("4th") );
00263   mByDayCombo->insertItem( i18n("5th") );
00264   mByDayCombo->insertItem( i18n("6th") );
00265   mByDayCombo->insertItem( i18n("7th") );
00266   mByDayCombo->insertItem( i18n("8th") );
00267   mByDayCombo->insertItem( i18n("9th") );
00268   mByDayCombo->insertItem( i18n("10th") );
00269   mByDayCombo->insertItem( i18n("11th") );
00270   mByDayCombo->insertItem( i18n("12th") );
00271   mByDayCombo->insertItem( i18n("13th") );
00272   mByDayCombo->insertItem( i18n("14th") );
00273   mByDayCombo->insertItem( i18n("15th") );
00274   mByDayCombo->insertItem( i18n("16th") );
00275   mByDayCombo->insertItem( i18n("17th") );
00276   mByDayCombo->insertItem( i18n("18th") );
00277   mByDayCombo->insertItem( i18n("19th") );
00278   mByDayCombo->insertItem( i18n("20th") );
00279   mByDayCombo->insertItem( i18n("21st") );
00280   mByDayCombo->insertItem( i18n("22nd") );
00281   mByDayCombo->insertItem( i18n("23rd") );
00282   mByDayCombo->insertItem( i18n("24th") );
00283   mByDayCombo->insertItem( i18n("25th") );
00284   mByDayCombo->insertItem( i18n("26th") );
00285   mByDayCombo->insertItem( i18n("27th") );
00286   mByDayCombo->insertItem( i18n("28th") );
00287   mByDayCombo->insertItem( i18n("29th") );
00288   mByDayCombo->insertItem( i18n("30th") );
00289   mByDayCombo->insertItem( i18n("31st") );
00290   mByDayCombo->insertItem( i18n("Last") );
00291   mByDayCombo->insertItem( i18n("2nd Last") );
00292   mByDayCombo->insertItem( i18n("3rd Last") );
00293   mByDayCombo->insertItem( i18n("4th Last") );
00294   mByDayCombo->insertItem( i18n("5th Last") );
00295   // FIXME: After the string freeze is over, insert all possible values, not
00296   //        just the ones we already have translated:
00297 /*  mByDayCombo->insertItem( i18n("6th Last") );
00298   mByDayCombo->insertItem( i18n("7th Last") );
00299   mByDayCombo->insertItem( i18n("8th Last") );
00300   mByDayCombo->insertItem( i18n("9th Last") );
00301   mByDayCombo->insertItem( i18n("10th Last") );
00302   mByDayCombo->insertItem( i18n("11th Last") );
00303   mByDayCombo->insertItem( i18n("12th Last") );
00304   mByDayCombo->insertItem( i18n("13th Last") );
00305   mByDayCombo->insertItem( i18n("14th Last") );
00306   mByDayCombo->insertItem( i18n("15th Last") );
00307   mByDayCombo->insertItem( i18n("16th Last") );
00308   mByDayCombo->insertItem( i18n("17th Last") );
00309   mByDayCombo->insertItem( i18n("18th Last") );
00310   mByDayCombo->insertItem( i18n("19th Last") );
00311   mByDayCombo->insertItem( i18n("20th Last") );
00312   mByDayCombo->insertItem( i18n("21st Last") );
00313   mByDayCombo->insertItem( i18n("22nd Last") );
00314   mByDayCombo->insertItem( i18n("23rd Last") );
00315   mByDayCombo->insertItem( i18n("24th Last") );
00316   mByDayCombo->insertItem( i18n("25th Last") );
00317   mByDayCombo->insertItem( i18n("26th Last") );
00318   mByDayCombo->insertItem( i18n("27th Last") );
00319   mByDayCombo->insertItem( i18n("28th Last") );
00320   mByDayCombo->insertItem( i18n("29th Last") );
00321   mByDayCombo->insertItem( i18n("30th Last") );
00322   mByDayCombo->insertItem( i18n("31st Last") );*/
00323   buttonLayout->addWidget( mByDayCombo, 0, 1 );
00324 
00325   TQLabel *byDayLabel = new TQLabel( i18n("day"), buttonGroup );
00326   TQWhatsThis::add( byDayLabel, whatsThis );
00327   buttonLayout->addWidget( byDayLabel, 0, 2 );
00328 
00329 
00330   mByPosRadio = new TQRadioButton( recurOnText, buttonGroup);
00331   TQWhatsThis::add( mByPosRadio,
00332                    i18n("Sets a weekday and specific week in the month "
00333                         "on which this event or to-do should recur") );
00334   buttonLayout->addWidget( mByPosRadio, 1, 0 );
00335 
00336   mByPosCountCombo = createWeekCountCombo( buttonGroup );
00337   buttonLayout->addWidget( mByPosCountCombo, 1, 1 );
00338 
00339   mByPosWeekdayCombo = createWeekdayCombo( buttonGroup );
00340   buttonLayout->addWidget( mByPosWeekdayCombo, 1, 2 );
00341 }
00342 
00343 void RecurMonthly::setByDay( int day )
00344 {
00345   mByDayRadio->setChecked( true );
00346   // Days from the end are after the ones from the begin, so correct for the
00347   // negative sign and add 30 (index starting at 0)
00348   if ( day > 0 && day <= 31 )
00349     mByDayCombo->setCurrentItem( day-1 );
00350   else if ( day < 0 )
00351     mByDayCombo->setCurrentItem( 31 - 1 - day );
00352 }
00353 
00354 void RecurMonthly::setByPos( int count, int weekday )
00355 {
00356   mByPosRadio->setChecked( true );
00357   if (count>0)
00358     mByPosCountCombo->setCurrentItem( count - 1 );
00359   else
00360     // negative weeks means counted from the end of month
00361     mByPosCountCombo->setCurrentItem( -count + 4 );
00362   mByPosWeekdayCombo->setCurrentItem( weekday - 1 );
00363 }
00364 
00365 bool RecurMonthly::byDay()
00366 {
00367   return mByDayRadio->isChecked();
00368 }
00369 
00370 bool RecurMonthly::byPos()
00371 {
00372   return mByPosRadio->isChecked();
00373 }
00374 
00375 int RecurMonthly::day()
00376 {
00377   int day = mByDayCombo->currentItem();
00378   if ( day >= 31 ) day = 31-day-1;
00379   else ++day;
00380   return day;
00381 }
00382 
00383 int RecurMonthly::count()
00384 {
00385   int pos=mByPosCountCombo->currentItem();
00386   if (pos<=4) // positive  count
00387     return pos+1;
00388   else
00389     return -pos+4;
00390 }
00391 
00392 int RecurMonthly::weekday()
00393 {
00394   return mByPosWeekdayCombo->currentItem() + 1;
00395 }
00396 
00398 
00399 RecurYearly::RecurYearly( TQWidget *parent, const char *name ) :
00400   RecurBase( parent, name )
00401 {
00402   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00403   topLayout->setSpacing( KDialog::spacingHint() );
00404 
00405   createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("year(s)") );
00406 
00407 
00408   TQButtonGroup *buttonGroup = new TQButtonGroup( this );
00409   buttonGroup->setFrameStyle( TQFrame::NoFrame );
00410   topLayout->addWidget( buttonGroup, 1, AlignVCenter );
00411 
00412   TQBoxLayout *buttonLayout = new TQVBoxLayout( buttonGroup );
00413 
00414 
00415   /* YearlyMonth (day n of Month Y) */
00416   TQBoxLayout *monthLayout = new TQHBoxLayout( buttonLayout );
00417   TQString recurInMonthText(
00418       i18n("part before XXX of 'Recur on day XXX of month YYY'",
00419       "&Recur on day "));
00420   if ( KOPrefs::instance()->mCompactDialogs ) {
00421     recurInMonthText = i18n("&Day ");
00422   }
00423   mByMonthRadio = new TQRadioButton( recurInMonthText, buttonGroup );
00424   TQWhatsThis::add( mByMonthRadio,
00425        i18n("Sets a specific day in a specific month on which "
00426       "this event or to-do should recur.") );
00427   monthLayout->addWidget( mByMonthRadio );
00428   mByMonthSpin = new TQSpinBox( 1, 31, 1, buttonGroup );
00429   TQWhatsThis::add( mByMonthSpin,
00430        i18n("The day of the month on which this event or to-do "
00431       "should recur.") );
00432   monthLayout->addWidget( mByMonthSpin );
00433   TQLabel *ofLabel = new TQLabel(
00434       i18n("part between XXX and YYY of 'Recur on day XXX of month YYY'", " &of "),
00435       buttonGroup );
00436   //What do I do here? I'm not sure if this label should have What's This in it... - Antonio
00437   monthLayout->addWidget( ofLabel );
00438 
00439   mByMonthCombo = createMonthNameCombo( buttonGroup );
00440   monthLayout->addWidget( mByMonthCombo );
00441   ofLabel->setBuddy( mByMonthCombo );
00442 
00443   monthLayout->addStretch( 1 );
00444 
00445 
00446   /* YearlyPos (weekday X of week N of month Y) */
00447   TQBoxLayout *posLayout = new TQHBoxLayout( buttonLayout );
00448   TQString recurOnPosText( i18n("Part before XXX in 'Recur on NNN. WEEKDAY of MONTH', short version", "&On" ) );
00449   if ( !KOPrefs::instance()->mCompactDialogs ) {
00450     recurOnPosText = i18n("Part before XXX in 'Recur on NNN. WEEKDAY of MONTH'", "&On the" );
00451   }
00452   mByPosRadio = new TQRadioButton( recurOnPosText, buttonGroup );
00453   TQWhatsThis::add( mByPosRadio,
00454        i18n("Sets a specific day in a specific week of a specific "
00455       "month on which this event or to-do should recur.") );
00456   posLayout->addWidget( mByPosRadio );
00457 
00458   mByPosDayCombo = createWeekCountCombo( buttonGroup );
00459   posLayout->addWidget( mByPosDayCombo );
00460 
00461   mByPosWeekdayCombo = createWeekdayCombo( buttonGroup );
00462   posLayout->addWidget( mByPosWeekdayCombo );
00463 
00464   ofLabel = new TQLabel(
00465       i18n("part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH'", " o&f "),
00466       buttonGroup );
00467   posLayout->addWidget( ofLabel );
00468 
00469   mByPosMonthCombo  = createMonthNameCombo( buttonGroup );
00470   posLayout->addWidget( mByPosMonthCombo );
00471   ofLabel->setBuddy( mByPosMonthCombo );
00472 
00473   posLayout->addStretch( 1 );
00474 
00475 
00476   /* YearlyDay (day N of the year) */
00477   TQBoxLayout *dayLayout = new TQHBoxLayout( buttonLayout );
00478   TQString recurOnDayText;
00479   if ( KOPrefs::instance()->mCompactDialogs ) {
00480     recurOnDayText = i18n("Day #");
00481   } else {
00482     recurOnDayText = i18n("Recur on &day #");
00483   }
00484   TQString whatsThis = i18n("Sets a specific day within the year on which this "
00485          "event or to-do should recur.");
00486   mByDayRadio = new TQRadioButton( recurOnDayText, buttonGroup );
00487   TQWhatsThis::add( mByDayRadio, whatsThis );
00488   dayLayout->addWidget( mByDayRadio );
00489 
00490   mByDaySpin = new TQSpinBox( 1, 366, 1, buttonGroup );
00491   TQWhatsThis::add( mByDaySpin, whatsThis );
00492 
00493   dayLayout->addWidget( mByDaySpin );
00494 
00495   TQString ofTheYear( i18n("part after NNN of 'Recur on day #NNN of the year'", " of the &year"));
00496   if ( KOPrefs::instance()->mCompactDialogs ) {
00497     ofTheYear = i18n("part after NNN of 'Recur on day #NNN of the year', short version",
00498         " of the year");
00499   }
00500   ofLabel = new TQLabel( ofTheYear, buttonGroup );
00501   TQWhatsThis::add( ofLabel, whatsThis );
00502   dayLayout->addWidget( ofLabel );
00503   ofLabel->setBuddy( mByDaySpin );
00504 
00505   dayLayout->addStretch( 1 );
00506 }
00507 
00508 void RecurYearly::setByDay( int day )
00509 {
00510   mByDayRadio->setChecked( true );
00511   mByDaySpin->setValue( day );
00512 }
00513 
00514 void RecurYearly::setByPos( int count, int weekday, int month )
00515 {
00516   mByPosRadio->setChecked( true );
00517   if ( count > 0 )
00518     mByPosDayCombo->setCurrentItem( count - 1 );
00519   else
00520     mByPosDayCombo->setCurrentItem( -count + 4 );
00521   mByPosWeekdayCombo->setCurrentItem( weekday - 1 );
00522   mByPosMonthCombo->setCurrentItem( month-1 );
00523 }
00524 
00525 void RecurYearly::setByMonth( int day, int month )
00526 {
00527   mByMonthRadio->setChecked( true );
00528   mByMonthSpin->setValue( day );
00529   mByMonthCombo->setCurrentItem( month - 1 );
00530 }
00531 
00532 RecurYearly::YearlyType RecurYearly::getType()
00533 {
00534   if ( mByMonthRadio->isChecked() ) return byMonth;
00535   if ( mByPosRadio->isChecked() ) return byPos;
00536   if ( mByDayRadio->isChecked() ) return byDay;
00537   return byMonth;
00538 }
00539 
00540 int RecurYearly::monthDay()
00541 {
00542   return mByMonthSpin->value();
00543 }
00544 
00545 int RecurYearly::month()
00546 {
00547   return mByMonthCombo->currentItem() + 1;
00548 }
00549 
00550 int RecurYearly::posCount()
00551 {
00552   int pos = mByPosDayCombo->currentItem();
00553   if ( pos <= 4 ) // positive  count
00554     return pos + 1;
00555   else
00556     return -pos + 4;
00557 }
00558 
00559 int RecurYearly::posWeekday()
00560 {
00561   return mByPosWeekdayCombo->currentItem() + 1;
00562 }
00563 
00564 int RecurYearly::posMonth()
00565 {
00566   return mByPosMonthCombo->currentItem() + 1;
00567 }
00568 
00569 int RecurYearly::day()
00570 {
00571   return mByDaySpin->value();
00572 }
00573 
00575 
00576 ExceptionsWidget::ExceptionsWidget( TQWidget *parent, const char *name ) :
00577   TQWidget( parent, name )
00578 {
00579   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00580 
00581   TQGroupBox *groupBox = new TQGroupBox( 1, Qt::Horizontal, i18n("E&xceptions"),
00582                                        this );
00583   topLayout->addWidget( groupBox );
00584 
00585   TQWidget *box = new TQWidget( groupBox );
00586 
00587   TQGridLayout *boxLayout = new TQGridLayout( box );
00588 
00589   mExceptionDateEdit = new KDateEdit( box );
00590   TQWhatsThis::add( mExceptionDateEdit,
00591        i18n("A date that should be considered an exception "
00592       "to the recurrence rules for this event or to-do.") );
00593   mExceptionDateEdit->setDate( TQDate::currentDate() );
00594   boxLayout->addWidget( mExceptionDateEdit, 0, 0 );
00595 
00596   TQPushButton *addExceptionButton = new TQPushButton(
00597       i18n( "Add a new recurrence to the recurrence list", "&Add" ), box );
00598   TQWhatsThis::add( addExceptionButton,
00599        i18n("Add this date as an exception "
00600       "to the recurrence rules for this event or to-do.") );
00601   boxLayout->addWidget( addExceptionButton, 1, 0 );
00602   TQPushButton *changeExceptionButton = new TQPushButton( i18n("&Change"), box );
00603   TQWhatsThis::add( changeExceptionButton,
00604        i18n("Replace the currently selected date with this date.") );
00605   boxLayout->addWidget( changeExceptionButton, 2, 0 );
00606   TQPushButton *deleteExceptionButton = new TQPushButton( i18n("&Delete"), box );
00607   TQWhatsThis::add( deleteExceptionButton,
00608        i18n("Delete the currently selected date from the list of dates "
00609             "that should be considered exceptions to the recurrence rules "
00610             "for this event or to-do.") );
00611   boxLayout->addWidget( deleteExceptionButton, 3, 0 );
00612 
00613   mExceptionList = new TQListBox( box );
00614   TQWhatsThis::add( mExceptionList,
00615        i18n("Displays current dates that are being considered "
00616       "exceptions to the recurrence rules for this event "
00617       "or to-do.") );
00618   boxLayout->addMultiCellWidget( mExceptionList, 0, 3, 1, 1 );
00619 
00620   boxLayout->setRowStretch( 4, 1 );
00621   boxLayout->setColStretch( 1, 3 );
00622 
00623   connect( addExceptionButton, TQT_SIGNAL( clicked() ),
00624            TQT_SLOT( addException() ) );
00625   connect( changeExceptionButton, TQT_SIGNAL( clicked() ),
00626            TQT_SLOT( changeException() ) );
00627   connect( deleteExceptionButton, TQT_SIGNAL( clicked() ),
00628            TQT_SLOT( deleteException() ) );
00629 }
00630 
00631 void ExceptionsWidget::addException()
00632 {
00633   TQDate date = mExceptionDateEdit->date();
00634   TQString dateStr = TDEGlobal::locale()->formatDate( date );
00635   if( !mExceptionList->findItem( dateStr ) ) {
00636     mExceptionDates.append( date );
00637     mExceptionList->insertItem( dateStr );
00638   }
00639 }
00640 
00641 void ExceptionsWidget::changeException()
00642 {
00643   int pos = mExceptionList->currentItem();
00644   if ( pos < 0 ) return;
00645 
00646   TQDate date = mExceptionDateEdit->date();
00647   mExceptionDates[ pos ] = date;
00648   mExceptionList->changeItem( TDEGlobal::locale()->formatDate( date ), pos );
00649 }
00650 
00651 void ExceptionsWidget::deleteException()
00652 {
00653   int pos = mExceptionList->currentItem();
00654   if ( pos < 0 ) return;
00655 
00656   mExceptionDates.remove( mExceptionDates.at( pos ) );
00657   mExceptionList->removeItem( pos );
00658 }
00659 
00660 void ExceptionsWidget::setDates( const DateList &dates )
00661 {
00662   mExceptionList->clear();
00663   mExceptionDates.clear();
00664   DateList::ConstIterator dit;
00665   for ( dit = dates.begin(); dit != dates.end(); ++dit ) {
00666     mExceptionList->insertItem( TDEGlobal::locale()->formatDate(* dit ) );
00667     mExceptionDates.append( *dit );
00668   }
00669 }
00670 
00671 DateList ExceptionsWidget::dates()
00672 {
00673   return mExceptionDates;
00674 }
00675 
00677 
00678 ExceptionsDialog::ExceptionsDialog( TQWidget *parent, const char *name ) :
00679   KDialogBase( parent, name, true, i18n("Edit Exceptions"), Ok|Cancel )
00680 {
00681   mExceptions = new ExceptionsWidget( this );
00682   setMainWidget( mExceptions );
00683 }
00684 
00685 void ExceptionsDialog::setDates( const DateList &dates )
00686 {
00687   mExceptions->setDates( dates );
00688 }
00689 
00690 DateList ExceptionsDialog::dates()
00691 {
00692   return mExceptions->dates();
00693 }
00694 
00696 
00697 RecurrenceRangeWidget::RecurrenceRangeWidget( TQWidget *parent,
00698                                               const char *name )
00699   : TQWidget( parent, name )
00700 {
00701   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00702 
00703   mRangeGroupBox = new TQGroupBox( 1, Qt::Horizontal, i18n("Recurrence Range"),
00704                                   this );
00705   TQWhatsThis::add( mRangeGroupBox,
00706        i18n("Sets a range for which these recurrence rules will "
00707       "apply to this event or to-do.") );
00708   topLayout->addWidget( mRangeGroupBox );
00709 
00710   TQWidget *rangeBox = new TQWidget( mRangeGroupBox );
00711   TQVBoxLayout *rangeLayout = new TQVBoxLayout( rangeBox );
00712   rangeLayout->setSpacing( KDialog::spacingHint() );
00713 
00714   mStartDateLabel = new TQLabel( i18n("Begin on:"), rangeBox );
00715   TQWhatsThis::add( mStartDateLabel,
00716        i18n("The date on which the recurrences for this event or to-do "
00717       "should begin.") );
00718   rangeLayout->addWidget( mStartDateLabel );
00719 
00720   TQButtonGroup *rangeButtonGroup = new TQButtonGroup( this );
00721   rangeButtonGroup->hide();
00722 
00723   mNoEndDateButton = new TQRadioButton( i18n("&No ending date"), rangeBox );
00724   TQWhatsThis::add( mNoEndDateButton,
00725        i18n("Sets the event or to-do to recur forever.") );
00726   rangeButtonGroup->insert( mNoEndDateButton );
00727   rangeLayout->addWidget( mNoEndDateButton );
00728 
00729   TQBoxLayout *durationLayout = new TQHBoxLayout( rangeLayout );
00730   durationLayout->setSpacing( KDialog::spacingHint() );
00731 
00732   mEndDurationButton = new TQRadioButton( i18n("End &after"), rangeBox );
00733   TQWhatsThis::add( mEndDurationButton,
00734        i18n("Sets the event or to-do to stop recurring after a "
00735       "certain number of occurrences.") );
00736   rangeButtonGroup->insert( mEndDurationButton );
00737   durationLayout->addWidget( mEndDurationButton );
00738 
00739   TQString whatsThis = i18n("Number of times the event or to-do should recur "
00740            "before stopping.");
00741   mEndDurationEdit = new TQSpinBox( 1, 9999, 1, rangeBox );
00742   TQWhatsThis::add( mEndDurationEdit, whatsThis );
00743   durationLayout->addWidget( mEndDurationEdit );
00744 
00745   TQLabel *endDurationLabel = new TQLabel( i18n("&occurrence(s)"), rangeBox );
00746   TQWhatsThis::add( endDurationLabel, whatsThis );
00747   durationLayout ->addWidget( endDurationLabel );
00748   endDurationLabel->setBuddy( mEndDurationEdit );
00749 
00750   TQBoxLayout *endDateLayout = new TQHBoxLayout( rangeLayout );
00751   endDateLayout->setSpacing( KDialog::spacingHint() );
00752 
00753   mEndDateButton = new TQRadioButton( i18n("End &on:"), rangeBox );
00754   TQWhatsThis::add( mEndDateButton,
00755                    i18n("Sets the event or to-do to stop recurring on "
00756                         "a certain date.") );
00757   rangeButtonGroup->insert( mEndDateButton );
00758   endDateLayout->addWidget( mEndDateButton );
00759 
00760   mEndDateEdit = new KDateEdit( rangeBox );
00761   TQWhatsThis::add( mEndDateEdit,
00762                    i18n("Date after which the event or to-do should stop "
00763                         "recurring") );
00764   endDateLayout->addWidget( mEndDateEdit );
00765 
00766   endDateLayout->addStretch( 1 );
00767 
00768   connect( mNoEndDateButton, TQT_SIGNAL( toggled( bool ) ),
00769            TQT_SLOT( showCurrentRange() ) );
00770   connect( mEndDurationButton, TQT_SIGNAL( toggled( bool ) ),
00771            TQT_SLOT( showCurrentRange() ) );
00772   connect( mEndDateButton, TQT_SIGNAL( toggled( bool ) ),
00773            TQT_SLOT( showCurrentRange() ) );
00774 }
00775 
00776 void RecurrenceRangeWidget::setDefaults( const TQDateTime &from  )
00777 {
00778   mNoEndDateButton->setChecked( true );
00779 
00780   setDateTimes( from );
00781   setEndDate( from.date() );
00782 }
00783 
00784 void RecurrenceRangeWidget::setDuration( int duration )
00785 {
00786   if ( duration == -1 ) {
00787     mNoEndDateButton->setChecked( true );
00788   } else if ( duration == 0 ) {
00789     mEndDateButton->setChecked( true );
00790   } else {
00791     mEndDurationButton->setChecked( true );
00792     mEndDurationEdit->setValue( duration );
00793   }
00794 }
00795 
00796 int RecurrenceRangeWidget::duration()
00797 {
00798   if ( mNoEndDateButton->isChecked() ) {
00799     return -1;
00800   } else if ( mEndDurationButton->isChecked() ) {
00801     return mEndDurationEdit->value();
00802   } else {
00803     return 0;
00804   }
00805 }
00806 
00807 void RecurrenceRangeWidget::setEndDate( const TQDate &date )
00808 {
00809   mEndDateEdit->setDate( date );
00810 }
00811 
00812 TQDate RecurrenceRangeWidget::endDate()
00813 {
00814   return mEndDateEdit->date();
00815 }
00816 
00817 void RecurrenceRangeWidget::showCurrentRange()
00818 {
00819   mEndDurationEdit->setEnabled( mEndDurationButton->isChecked() );
00820   mEndDateEdit->setEnabled( mEndDateButton->isChecked() );
00821 }
00822 
00823 void RecurrenceRangeWidget::setDateTimes( const TQDateTime &start,
00824                                           const TQDateTime & )
00825 {
00826   mStartDateLabel->setText( i18n("Begins on: %1")
00827       .arg( TDEGlobal::locale()->formatDate( start.date() ) ) );
00828 }
00829 
00831 
00832 RecurrenceRangeDialog::RecurrenceRangeDialog( TQWidget *parent,
00833                                               const char *name ) :
00834   KDialogBase( parent, name, true, i18n("Edit Recurrence Range"), Ok|Cancel )
00835 {
00836   mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
00837   setMainWidget( mRecurrenceRangeWidget );
00838 }
00839 
00840 void RecurrenceRangeDialog::setDefaults( const TQDateTime &from )
00841 {
00842   mRecurrenceRangeWidget->setDefaults( from );
00843 }
00844 
00845 void RecurrenceRangeDialog::setDuration( int duration )
00846 {
00847   mRecurrenceRangeWidget->setDuration( duration );
00848 }
00849 
00850 int RecurrenceRangeDialog::duration()
00851 {
00852   return mRecurrenceRangeWidget->duration();
00853 }
00854 
00855 void RecurrenceRangeDialog::setEndDate( const TQDate &date )
00856 {
00857   mRecurrenceRangeWidget->setEndDate( date );
00858 }
00859 
00860 TQDate RecurrenceRangeDialog::endDate()
00861 {
00862   return mRecurrenceRangeWidget->endDate();
00863 }
00864 
00865 void RecurrenceRangeDialog::setDateTimes( const TQDateTime &start,
00866                                           const TQDateTime &end )
00867 {
00868   mRecurrenceRangeWidget->setDateTimes( start, end );
00869 }
00870 
00872 
00873 RecurrenceChooser::RecurrenceChooser( TQWidget *parent, const char *name ) :
00874   TQWidget( parent, name )
00875 {
00876   TQBoxLayout *topLayout = new TQVBoxLayout( this );
00877 
00878   if ( KOPrefs::instance()->mCompactDialogs ) {
00879     mTypeCombo = new TQComboBox( this );
00880     TQWhatsThis::add( mTypeCombo,
00881                      i18n("Sets the type of recurrence this event or to-do "
00882                           "should have.") );
00883     mTypeCombo->insertItem( i18n("Daily") );
00884     mTypeCombo->insertItem( i18n("Weekly") );
00885     mTypeCombo->insertItem( i18n("Monthly") );
00886     mTypeCombo->insertItem( i18n("Yearly") );
00887 
00888     topLayout->addWidget( mTypeCombo );
00889 
00890     connect( mTypeCombo, TQT_SIGNAL( activated( int ) ), TQT_SLOT( emitChoice() ) );
00891   } else {
00892     mTypeCombo = 0;
00893 
00894     TQButtonGroup *ruleButtonGroup = new TQButtonGroup( 1, Qt::Horizontal, this );
00895     ruleButtonGroup->setFrameStyle( TQFrame::NoFrame );
00896     topLayout->addWidget( ruleButtonGroup );
00897 
00898     mDailyButton = new TQRadioButton( i18n("&Daily"), ruleButtonGroup );
00899     TQWhatsThis::add( mDailyButton,
00900                      i18n("Sets the event or to-do to recur daily according "
00901                           "to the specified rules.") );
00902     mWeeklyButton = new TQRadioButton( i18n("&Weekly"), ruleButtonGroup );
00903     TQWhatsThis::add( mWeeklyButton,
00904                      i18n("Sets the event or to-do to recur weekly according "
00905                           "to the specified rules.") );
00906     mMonthlyButton = new TQRadioButton( i18n("&Monthly"), ruleButtonGroup );
00907     TQWhatsThis::add( mMonthlyButton,
00908                      i18n("Sets the event or to-do to recur monthly according "
00909                           "to the specified rules.") );
00910     mYearlyButton = new TQRadioButton( i18n("&Yearly"), ruleButtonGroup );
00911     TQWhatsThis::add( mYearlyButton,
00912                      i18n("Sets the event or to-do to recur yearly according "
00913                           "to the specified rules.") );
00914 
00915     connect( mDailyButton, TQT_SIGNAL( toggled( bool ) ),
00916              TQT_SLOT( emitChoice() ) );
00917     connect( mWeeklyButton, TQT_SIGNAL( toggled( bool ) ),
00918              TQT_SLOT( emitChoice() ) );
00919     connect( mMonthlyButton, TQT_SIGNAL( toggled( bool ) ),
00920              TQT_SLOT( emitChoice() ) );
00921     connect( mYearlyButton, TQT_SIGNAL( toggled( bool ) ),
00922              TQT_SLOT( emitChoice() ) );
00923   }
00924 }
00925 
00926 int RecurrenceChooser::type()
00927 {
00928   if ( mTypeCombo ) {
00929     return mTypeCombo->currentItem();
00930   } else {
00931     if ( mDailyButton->isChecked() ) return Daily;
00932     else if ( mWeeklyButton->isChecked() ) return Weekly;
00933     else if ( mMonthlyButton->isChecked() ) return Monthly;
00934     else return Yearly;
00935   }
00936 }
00937 
00938 void RecurrenceChooser::setType( int type )
00939 {
00940   if ( mTypeCombo ) {
00941     mTypeCombo->setCurrentItem( type );
00942   } else {
00943     switch ( type ) {
00944       case Daily:
00945         mDailyButton->setChecked( true );
00946         break;
00947       case Weekly:
00948         mWeeklyButton->setChecked( true );
00949         break;
00950       case Monthly:
00951         mMonthlyButton->setChecked( true );
00952         break;
00953       case Yearly:
00954       default:
00955         mYearlyButton->setChecked( true );
00956         break;
00957     }
00958   }
00959 }
00960 
00961 void RecurrenceChooser::emitChoice()
00962 {
00963   emit chosen ( type() );
00964 }
00965 
00967 
00968 KOEditorRecurrence::KOEditorRecurrence( TQWidget* parent, const char *name ) :
00969   TQWidget( parent, name )
00970 {
00971   TQGridLayout *topLayout = new TQGridLayout( this );
00972   topLayout->setSpacing( KDialog::spacingHint() );
00973 
00974   mEnabledCheck = new TQCheckBox( i18n("&Enable recurrence"), this );
00975   TQWhatsThis::add( mEnabledCheck,
00976                    i18n("Enables recurrence for this event or to-do according "
00977                         "to the specified rules.") );
00978   connect( mEnabledCheck, TQT_SIGNAL( toggled( bool ) ),
00979            TQT_SLOT( setRecurrenceEnabled( bool ) ) );
00980   topLayout->addMultiCellWidget( mEnabledCheck, 0, 0, 0, 1 );
00981 
00982 
00983   mTimeGroupBox = new TQGroupBox( 1, Qt::Horizontal, i18n("Appointment Time "),
00984                                  this );
00985   TQWhatsThis::add( mTimeGroupBox,
00986                    i18n("Displays appointment time information.") );
00987   topLayout->addMultiCellWidget( mTimeGroupBox, 1, 1 , 0 , 1 );
00988 
00989   if ( KOPrefs::instance()->mCompactDialogs ) {
00990     mTimeGroupBox->hide();
00991   }
00992 
00993 //  TQFrame *timeFrame = new TQFrame( mTimeGroupBox );
00994 //  TQBoxLayout *layoutTimeFrame = new TQHBoxLayout( timeFrame );
00995 //  layoutTimeFrame->setSpacing( KDialog::spacingHint() );
00996 
00997   mDateTimeLabel = new TQLabel( mTimeGroupBox );
00998 //  mDateTimeLabel = new TQLabel( timeFrame );
00999 //  layoutTimeFrame->addWidget( mDateTimeLabel );
01000 
01001   Qt::Orientation orientation;
01002   if ( KOPrefs::instance()->mCompactDialogs ) orientation = Qt::Horizontal;
01003   else orientation = Qt::Vertical;
01004 
01005   mRuleBox = new TQGroupBox( 1, orientation, i18n("Recurrence Rule"), this );
01006   TQWhatsThis::add( mRuleBox,
01007                    i18n("Options concerning the type of recurrence this event "
01008                         "or to-do should have.") );
01009   if ( KOPrefs::instance()->mCompactDialogs ) {
01010     topLayout->addWidget( mRuleBox, 2, 0 );
01011   } else {
01012     topLayout->addMultiCellWidget( mRuleBox, 2, 2, 0, 1 );
01013   }
01014 
01015   mRecurrenceChooser = new RecurrenceChooser( mRuleBox );
01016   connect( mRecurrenceChooser, TQT_SIGNAL( chosen( int ) ),
01017            TQT_SLOT( showCurrentRule( int ) ) );
01018 
01019   if ( !KOPrefs::instance()->mCompactDialogs ) {
01020     TQFrame *ruleSepFrame = new TQFrame( mRuleBox );
01021     ruleSepFrame->setFrameStyle( TQFrame::VLine | TQFrame::Sunken );
01022   }
01023 
01024   mRuleStack = new TQWidgetStack( mRuleBox );
01025 
01026   mDaily = new RecurDaily( mRuleStack );
01027   mRuleStack->addWidget( mDaily, 0 );
01028 
01029   mWeekly = new RecurWeekly( mRuleStack );
01030   mRuleStack->addWidget( mWeekly, 0 );
01031 
01032   mMonthly = new RecurMonthly( mRuleStack );
01033   mRuleStack->addWidget( mMonthly, 0 );
01034 
01035   mYearly = new RecurYearly( mRuleStack );
01036   mRuleStack->addWidget( mYearly, 0 );
01037 
01038   showCurrentRule( mRecurrenceChooser->type() );
01039 
01040   if ( KOPrefs::instance()->mCompactDialogs ) {
01041     mRecurrenceRangeWidget = 0;
01042     mRecurrenceRangeDialog = new RecurrenceRangeDialog( this );
01043     mRecurrenceRange = mRecurrenceRangeDialog;
01044     mRecurrenceRangeButton = new TQPushButton( i18n("Recurrence Range..."),
01045                                               this );
01046     TQWhatsThis::add( mRecurrenceRangeButton,
01047                      i18n("Options concerning the time range during which "
01048                           "this event or to-do should recur.") );
01049     topLayout->addWidget( mRecurrenceRangeButton, 3, 0 );
01050     connect( mRecurrenceRangeButton, TQT_SIGNAL( clicked() ),
01051              TQT_SLOT( showRecurrenceRangeDialog() ) );
01052 
01053     mExceptionsWidget = 0;
01054     mExceptionsDialog = new ExceptionsDialog( this );
01055     mExceptions = mExceptionsDialog;
01056     mExceptionsButton = new TQPushButton( i18n("Exceptions..."), this );
01057     topLayout->addWidget( mExceptionsButton, 4, 0 );
01058     connect( mExceptionsButton, TQT_SIGNAL( clicked() ),
01059              TQT_SLOT( showExceptionsDialog() ) );
01060 
01061   } else {
01062     mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
01063     TQWhatsThis::add( mRecurrenceRangeWidget,
01064                      i18n("Options concerning the time range during which "
01065                           "this event or to-do should recur.") );
01066     mRecurrenceRangeDialog = 0;
01067     mRecurrenceRange = mRecurrenceRangeWidget;
01068     mRecurrenceRangeButton = 0;
01069     topLayout->addWidget( mRecurrenceRangeWidget, 3, 0 );
01070 
01071     mExceptionsWidget = new ExceptionsWidget( this );
01072     mExceptionsDialog = 0;
01073     mExceptions = mExceptionsWidget;
01074     mExceptionsButton = 0;
01075     topLayout->addWidget( mExceptionsWidget, 3, 1 );
01076   }
01077 
01078   // set some initial defaults for the saved recurrence
01079   mSaveRec.setDuration( -1 ); // never ending
01080 }
01081 
01082 KOEditorRecurrence::~KOEditorRecurrence()
01083 {
01084 }
01085 
01086 void KOEditorRecurrence::setRecurrenceEnabled( bool enabled )
01087 {
01088 //  kdDebug(5850) << "KOEditorRecurrence::setRecurrenceEnabled(): " << (enabled ? "on" : "off") << endl;
01089 
01090   mEnabledCheck->setChecked( enabled );
01091   mTimeGroupBox->setEnabled( enabled );
01092   mRuleBox->setEnabled( enabled );
01093   if ( mRecurrenceRangeWidget ) mRecurrenceRangeWidget->setEnabled( enabled );
01094   if ( mRecurrenceRangeButton ) mRecurrenceRangeButton->setEnabled( enabled );
01095   if ( mExceptionsWidget ) mExceptionsWidget->setEnabled( enabled );
01096   if ( mExceptionsButton ) mExceptionsButton->setEnabled( enabled );
01097 }
01098 
01099 void KOEditorRecurrence::showCurrentRule( int current )
01100 {
01101   switch ( current ) {
01102     case Daily:
01103       mRuleStack->raiseWidget( mDaily );
01104       break;
01105     case Weekly:
01106       mRuleStack->raiseWidget( mWeekly );
01107       break;
01108     case Monthly:
01109       mRuleStack->raiseWidget( mMonthly );
01110       break;
01111     default:
01112     case Yearly:
01113       mRuleStack->raiseWidget( mYearly );
01114       break;
01115   }
01116 }
01117 
01118 void KOEditorRecurrence::setDateTimes( const TQDateTime &start, const TQDateTime &end )
01119 {
01120 //  kdDebug(5850) << "KOEditorRecurrence::setDateTimes" << endl;
01121 
01122   mEventStartDt = start;
01123   mRecurrenceRange->setDateTimes( start, end );
01124   mDaily->setDateTimes( start, end );
01125   mWeekly->setDateTimes( start, end );
01126   mMonthly->setDateTimes( start, end );
01127   mYearly->setDateTimes( start, end );
01128 
01129   // Now set the defaults for all unused types, use the start time for it
01130   bool enabled = mEnabledCheck->isChecked();
01131   int type = mRecurrenceChooser->type();
01132 
01133   if ( !enabled || type != RecurrenceChooser::Weekly ) {
01134     TQBitArray days( 7 );
01135     days.fill( 0 );
01136     days.setBit( (start.date().dayOfWeek()+6) % 7 );
01137     mWeekly->setDays( days );
01138   }
01139   if ( !enabled || type != RecurrenceChooser::Monthly ) {
01140     mMonthly->setByPos( ( start.date().day() - 1 ) / 7 + 1, start.date().dayOfWeek() - 1 );
01141     mMonthly->setByDay( start.date().day() );
01142   }
01143   if ( !enabled || type != RecurrenceChooser::Yearly ) {
01144     mYearly->setByDay( start.date().dayOfYear() );
01145     mYearly->setByPos( ( start.date().day() - 1 ) / 7 + 1,
01146         start.date().dayOfWeek() - 1, start.date().month() );
01147     mYearly->setByMonth( start.date().day(), start.date().month() );
01148   }
01149 }
01150 
01151 void KOEditorRecurrence::setDefaults( const TQDateTime &from, const TQDateTime &to, bool )
01152 {
01153   setDateTimes( from, to );
01154 
01155   setRecurrenceEnabled( false );
01156 
01157   mRecurrenceRange->setDefaults( from );
01158 
01159   mRecurrenceChooser->setType( RecurrenceChooser::Weekly );
01160   showCurrentRule( mRecurrenceChooser->type() );
01161 
01162   mDaily->setFrequency( 1 );
01163 
01164   mWeekly->setFrequency( 1 );
01165   TQBitArray days( 7 );
01166   days.fill( 0 );
01167   days.setBit( (from.date().dayOfWeek()+6) % 7 );
01168   mWeekly->setDays( days );
01169 
01170   mMonthly->setFrequency( 1 );
01171   mMonthly->setByPos( ( from.date().day() - 1 ) / 7 + 1, from.date().dayOfWeek() );
01172   mMonthly->setByDay( from.date().day() );
01173 
01174   mYearly->setFrequency( 1 );
01175   mYearly->setByDay( from.date().dayOfYear() );
01176   mYearly->setByPos( ( from.date().day() - 1 ) / 7 + 1,
01177       from.date().dayOfWeek(), from.date().month() );
01178   mYearly->setByMonth( from.date().day(), from.date().month() );
01179 }
01180 
01181 void KOEditorRecurrence::readIncidence(Incidence *incidence)
01182 {
01183   if (!incidence) return;
01184 
01185   TQBitArray rDays( 7 );
01186   int day = 0;
01187   int count = 0;
01188   int month = 0;
01189 
01190   if ( incidence->type() == "Todo" ) {
01191     Todo *todo = static_cast<Todo *>(incidence);
01192     setDefaults( todo->dtStart(true), todo->dtDue(), todo->doesFloat() );
01193   } else {
01194     setDefaults( incidence->dtStart(), incidence->dtEnd(), incidence->doesFloat() );
01195   }
01196 
01197   uint recurs = incidence->recurrenceType();
01198   int f = 0;
01199   Recurrence *r = 0;
01200 
01201   if ( recurs ) {
01202     r = incidence->recurrence();
01203     f = r->frequency();
01204   }
01205 
01206   setRecurrenceEnabled( recurs );
01207 
01208   int recurrenceType = RecurrenceChooser::Weekly;
01209 
01210   switch ( recurs ) {
01211     case Recurrence::rNone:
01212       break;
01213     case Recurrence::rDaily:
01214       recurrenceType = RecurrenceChooser::Daily;
01215       mDaily->setFrequency( f );
01216       break;
01217     case Recurrence::rWeekly:
01218       recurrenceType = RecurrenceChooser::Weekly;
01219       mWeekly->setFrequency( f );
01220       mWeekly->setDays( r->days() );
01221       break;
01222     case Recurrence::rMonthlyPos: {
01223       // TODO: we only handle one possibility in the list right now,
01224       // so I have hardcoded calls with first().  If we make the GUI
01225       // more extended, this can be changed.
01226       recurrenceType = RecurrenceChooser::Monthly;
01227 
01228       TQValueList<RecurrenceRule::WDayPos> rmp = r->monthPositions();
01229       if ( !rmp.isEmpty() ) {
01230         mMonthly->setByPos( rmp.first().pos(), rmp.first().day() );
01231       }
01232 
01233       mMonthly->setFrequency( f );
01234 
01235       break; }
01236     case Recurrence::rMonthlyDay: {
01237       recurrenceType = RecurrenceChooser::Monthly;
01238 
01239       TQValueList<int> rmd = r->monthDays();
01240       // check if we have any setting for which day (vcs import is broken and
01241       // does not set any day, thus we need to check)
01242       if ( rmd.isEmpty() ) {
01243         day = incidence->dtStart().date().day();
01244       } else {
01245         day = rmd.first();
01246       }
01247       mMonthly->setByDay( day );
01248 
01249       mMonthly->setFrequency( f );
01250 
01251       break; }
01252     case Recurrence::rYearlyMonth: {
01253       recurrenceType = RecurrenceChooser::Yearly;
01254       TQValueList<int> rmd = r->yearDates();
01255       if ( rmd.isEmpty() ) {
01256         day = incidence->dtStart().date().day();
01257       } else {
01258         day = rmd.first();
01259       }
01260       int month = incidence->dtStart().date().month();
01261       rmd = r->yearMonths();
01262       if ( !rmd.isEmpty() )
01263         month = rmd.first();
01264       mYearly->setByMonth( day, month );
01265       mYearly->setFrequency( f );
01266       break; }
01267     case Recurrence::rYearlyPos: {
01268       recurrenceType = RecurrenceChooser::Yearly;
01269 
01270       TQValueList<int> months = r->yearMonths();
01271       if ( months.isEmpty() ) {
01272         month = incidence->dtStart().date().month();
01273       } else {
01274         month = months.first();
01275       }
01276 
01277       TQValueList<RecurrenceRule::WDayPos> pos = r->yearPositions();
01278 
01279       if ( pos.isEmpty() ) {
01280         // Use dtStart if nothing is given (shouldn't happen!)
01281         count = ( incidence->dtStart().date().day() - 1 ) / 7;
01282         day = incidence->dtStart().date().dayOfWeek();
01283       } else {
01284         count = pos.first().pos();
01285         day = pos.first().day();
01286       }
01287       mYearly->setByPos( count, day, month );
01288       mYearly->setFrequency( f );
01289       break; }
01290     case Recurrence::rYearlyDay: {
01291       recurrenceType = RecurrenceChooser::Yearly;
01292       TQValueList<int> days = r->yearDays();
01293       if ( days.isEmpty() ) {
01294         day = incidence->dtStart().date().dayOfYear();
01295       } else {
01296         day = days.first();
01297       }
01298       mYearly->setByDay( day );
01299 
01300       mYearly->setFrequency( f );
01301       break; }
01302     default:
01303       break;
01304   }
01305 
01306   mRecurrenceChooser->setType( recurrenceType );
01307   showCurrentRule( recurrenceType );
01308 
01309   mRecurrenceRange->setDateTimes( incidence->recurrence()->startDateTime() );
01310 
01311   if ( incidence->doesRecur() ) {
01312     mRecurrenceRange->setDuration( r->duration() );
01313     if ( r->duration() == 0 ) mRecurrenceRange->setEndDate( r->endDate() );
01314   }
01315 
01316   mExceptions->setDates( incidence->recurrence()->exDates() );
01317 }
01318 
01319 void KOEditorRecurrence::writeIncidence( Incidence *incidence )
01320 {
01321   if ( !mEnabledCheck->isChecked() || !isEnabled() )
01322   {
01323     if ( incidence->doesRecur() )
01324       incidence->recurrence()->unsetRecurs();
01325     return;
01326   }
01327 
01328   Recurrence *r = incidence->recurrence();
01329 
01330   // clear out any old settings;
01331   r->unsetRecurs();
01332 
01333   int duration = mRecurrenceRange->duration();
01334   TQDate endDate;
01335   if ( duration == 0 ) endDate = mRecurrenceRange->endDate();
01336 
01337   int recurrenceType = mRecurrenceChooser->type();
01338   if ( recurrenceType == RecurrenceChooser::Daily ) {
01339     r->setDaily( mDaily->frequency() );
01340   } else if ( recurrenceType == RecurrenceChooser::Weekly ) {
01341     r->setWeekly( mWeekly->frequency(), mWeekly->days() );
01342   } else if ( recurrenceType == RecurrenceChooser::Monthly ) {
01343     r->setMonthly( mMonthly->frequency() );
01344 
01345     if ( mMonthly->byPos() ) {
01346       int pos = mMonthly->count();
01347 
01348       TQBitArray days( 7 );
01349       days.fill( false );
01350       days.setBit( mMonthly->weekday() - 1 );
01351       r->addMonthlyPos( pos, days );
01352     } else {
01353       // it's by day
01354       r->addMonthlyDate( mMonthly->day() );
01355     }
01356   } else if ( recurrenceType == RecurrenceChooser::Yearly ) {
01357     r->setYearly( mYearly->frequency() );
01358 
01359     switch ( mYearly->getType() ) {
01360       case RecurYearly::byMonth:
01361         r->addYearlyDate( mYearly->monthDay() );
01362         r->addYearlyMonth( mYearly->month() );
01363         break;
01364       case RecurYearly::byPos:  {
01365         r->addYearlyMonth( mYearly->posMonth() );
01366         TQBitArray days( 7 );
01367         days.fill( false );
01368         days.setBit( mYearly->posWeekday() - 1 );
01369         r->addYearlyPos( mYearly->posCount(), days );
01370         break; }
01371       case RecurYearly::byDay:
01372         r->addYearlyDay( mYearly->day() );
01373         break;
01374     }
01375   } // end "Yearly"
01376 
01377   if ( duration > 0 )
01378     r->setDuration( duration );
01379   else if ( duration == 0 )
01380     r->setEndDate( endDate );
01381   incidence->recurrence()->setExDates( mExceptions->dates() );
01382 }
01383 
01384 void KOEditorRecurrence::setDateTimeStr( const TQString &str )
01385 {
01386   mDateTimeLabel->setText( str );
01387 }
01388 
01389 bool KOEditorRecurrence::validateInput()
01390 {
01391   // Check input here.
01392   // Check if the recurrence (if set to end at a date) is scheduled to end before the event starts.
01393   if ( mEnabledCheck->isChecked() && (mRecurrenceRange->duration()==0) &&
01394        mEventStartDt.isValid() && ((mRecurrenceRange->endDate())<mEventStartDt.date()) ) {
01395     KMessageBox::sorry( 0,
01396       i18n("The end date '%1' of the recurrence must be after the start date '%2' of the event.")
01397       .arg( TDEGlobal::locale()->formatDate( mRecurrenceRange->endDate() ) )
01398       .arg( TDEGlobal::locale()->formatDate( mEventStartDt.date() ) ) );
01399     return false;
01400   }
01401   int recurrenceType = mRecurrenceChooser->type();
01402   // Check if a weekly recurrence has at least one day selected
01403   // TODO: Get rid of this, it's not really needed (by default the day should be taken from dtStart)
01404   if( mEnabledCheck->isChecked() && recurrenceType == RecurrenceChooser::Weekly ) {
01405     const TQBitArray &days = mWeekly->days();
01406     bool valid = false;
01407     for ( int i=0; i<7; ++i ) valid = valid || days.testBit( i );
01408     if ( !valid ) {
01409       KMessageBox::sorry( 0,
01410         i18n("A weekly recurring event or task has to have at least one weekday "
01411              "associated with it.") );
01412       return false;
01413     }
01414   }
01415   return true;
01416 }
01417 
01418 void KOEditorRecurrence::showExceptionsDialog()
01419 {
01420   DateList dates = mExceptions->dates();
01421   int result = mExceptionsDialog->exec();
01422   if ( result == TQDialog::Rejected ) mExceptions->setDates( dates );
01423 }
01424 
01425 void KOEditorRecurrence::showRecurrenceRangeDialog()
01426 {
01427   int duration = mRecurrenceRange->duration();
01428   TQDate endDate = mRecurrenceRange->endDate();
01429 
01430   int result = mRecurrenceRangeDialog->exec();
01431   if ( result == TQDialog::Rejected ) {
01432     mRecurrenceRange->setDuration( duration );
01433     mRecurrenceRange->setEndDate( endDate );
01434   }
01435 }
01436 
01437 bool KOEditorRecurrence::doesRecur()
01438 {
01439   return mEnabledCheck->isChecked();
01440 }
01441 
01442 void KOEditorRecurrence::saveValues()
01443 {
01444   int duration = mRecurrenceRange->duration();
01445   TQDate endDate;
01446   if ( duration == 0 ) {
01447     endDate = mRecurrenceRange->endDate();
01448   }
01449 
01450   int recurrenceType = mRecurrenceChooser->type();
01451   if ( recurrenceType == RecurrenceChooser::Daily ) {
01452     mSaveRec.setDaily( mDaily->frequency() );
01453   } else if ( recurrenceType == RecurrenceChooser::Weekly ) {
01454     mSaveRec.setWeekly( mWeekly->frequency(), mWeekly->days() );
01455   } else if ( recurrenceType == RecurrenceChooser::Monthly ) {
01456     mSaveRec.setMonthly( mMonthly->frequency() );
01457 
01458     if ( mMonthly->byPos() ) {
01459       int pos = mMonthly->count();
01460 
01461       TQBitArray days( 7 );
01462       days.fill( false );
01463       days.setBit( mMonthly->weekday() - 1 );
01464       mSaveRec.addMonthlyPos( pos, days );
01465     } else {
01466       // it's by day
01467       mSaveRec.addMonthlyDate( mMonthly->day() );
01468     }
01469   } else if ( recurrenceType == RecurrenceChooser::Yearly ) {
01470     mSaveRec.setYearly( mYearly->frequency() );
01471 
01472     switch ( mYearly->getType() ) {
01473     case RecurYearly::byMonth:
01474       mSaveRec.addYearlyDate( mYearly->monthDay() );
01475       mSaveRec.addYearlyMonth( mYearly->month() );
01476       break;
01477 
01478     case RecurYearly::byPos:
01479     {
01480       mSaveRec.addYearlyMonth( mYearly->posMonth() );
01481       TQBitArray days( 7 );
01482       days.fill( false );
01483       days.setBit( mYearly->posWeekday() - 1 );
01484       mSaveRec.addYearlyPos( mYearly->posCount(), days );
01485       break;
01486     }
01487 
01488     case RecurYearly::byDay:
01489       mSaveRec.addYearlyDay( mYearly->day() );
01490       break;
01491     }
01492   }
01493 
01494  if ( duration > 0 ) {
01495     mSaveRec.setDuration( duration );
01496   } else if ( duration == 0 ) {
01497     mSaveRec.setEndDate( endDate );
01498   }
01499 
01500   mSaveRec.setExDates( mExceptions->dates() );
01501 }
01502 
01503 void KOEditorRecurrence::restoreValues()
01504 {
01505   TQBitArray rDays( 7 );
01506   int day = 0;
01507   int count = 0;
01508   int month = 0;
01509 
01510   if ( mSaveRec.startDateTime().isValid() && mSaveRec.endDateTime().isValid() ) {
01511     setDefaults( mSaveRec.startDateTime(), mSaveRec.endDateTime(), mSaveRec.doesFloat() );
01512   }
01513 
01514   int recurrenceType;
01515   switch ( mSaveRec.recurrenceType() ) {
01516   case Recurrence::rNone:
01517     recurrenceType = RecurrenceChooser::Weekly;
01518     break;
01519 
01520   case Recurrence::rDaily:
01521     recurrenceType = RecurrenceChooser::Daily;
01522     mDaily->setFrequency( mSaveRec.frequency() );
01523     break;
01524 
01525   case Recurrence::rWeekly:
01526     recurrenceType = RecurrenceChooser::Weekly;
01527 
01528     mWeekly->setFrequency( mSaveRec.frequency() );
01529     mWeekly->setDays( mSaveRec.days() );
01530     break;
01531 
01532   case Recurrence::rMonthlyPos:
01533   {
01534     // TODO: we only handle one possibility in the list right now,
01535     // so I have hardcoded calls with first().  If we make the GUI
01536     // more extended, this can be changed.
01537     recurrenceType = RecurrenceChooser::Monthly;
01538 
01539     TQValueList<RecurrenceRule::WDayPos> rmp = mSaveRec.monthPositions();
01540     if ( !rmp.isEmpty() ) {
01541       mMonthly->setByPos( rmp.first().pos(), rmp.first().day() );
01542     }
01543     mMonthly->setFrequency( mSaveRec.frequency() );
01544     break;
01545   }
01546 
01547   case Recurrence::rMonthlyDay:
01548   {
01549     recurrenceType = RecurrenceChooser::Monthly;
01550 
01551     TQValueList<int> rmd = mSaveRec.monthDays();
01552     // check if we have any setting for which day (vcs import is broken and
01553     // does not set any day, thus we need to check)
01554     if ( !rmd.isEmpty() ) {
01555       day = rmd.first();
01556     }
01557     if ( day > 0 ) {
01558       mMonthly->setByDay( day );
01559       mMonthly->setFrequency( mSaveRec.frequency() );
01560     }
01561     break;
01562   }
01563 
01564   case Recurrence::rYearlyMonth:
01565   {
01566     recurrenceType = RecurrenceChooser::Yearly;
01567 
01568     TQValueList<int> rmd = mSaveRec.yearDates();
01569     if ( !rmd.isEmpty() ) {
01570       day = rmd.first();
01571     }
01572     rmd = mSaveRec.yearMonths();
01573     if ( !rmd.isEmpty() ) {
01574       month = rmd.first();
01575     }
01576     if ( day > 0 && month > 0 ) {
01577       mYearly->setByMonth( day, month );
01578       mYearly->setFrequency( mSaveRec.frequency() );
01579     }
01580     break;
01581   }
01582 
01583   case Recurrence::rYearlyPos:
01584   {
01585     recurrenceType = RecurrenceChooser::Yearly;
01586 
01587     TQValueList<int> months = mSaveRec.yearMonths();
01588     if ( !months.isEmpty() ) {
01589       month = months.first();
01590     }
01591     TQValueList<RecurrenceRule::WDayPos> pos = mSaveRec.yearPositions();
01592     if ( !pos.isEmpty() ) {
01593       count = pos.first().pos();
01594       day = pos.first().day();
01595     }
01596     if ( count > 0 && day > 0 && month > 0 ) {
01597       mYearly->setByPos( count, day, month );
01598       mYearly->setFrequency( mSaveRec.frequency() );
01599     }
01600     break;
01601   }
01602 
01603   case Recurrence::rYearlyDay:
01604   {
01605     recurrenceType = RecurrenceChooser::Yearly;
01606 
01607     TQValueList<int> days = mSaveRec.yearDays();
01608     if ( !days.isEmpty() ) {
01609       day = days.first();
01610     }
01611     if ( day > 0 ) {
01612       mYearly->setByDay( day );
01613       mYearly->setFrequency( mSaveRec.frequency() );
01614     }
01615     break;
01616   }
01617   default:
01618     break;
01619   }
01620 
01621   mRecurrenceChooser->setType( recurrenceType );
01622   showCurrentRule( recurrenceType );
01623 
01624   if ( mSaveRec.startDateTime().isValid() ) {
01625     mRecurrenceRange->setDateTimes( mSaveRec.startDateTime() );
01626   }
01627 
01628   mRecurrenceRange->setDuration( mSaveRec.duration() );
01629   if ( mSaveRec.duration() == 0 && mSaveRec.endDate().isValid() ) {
01630     mRecurrenceRange->setEndDate( mSaveRec.endDate() );
01631   }
01632 
01633   mExceptions->setDates( mSaveRec.exDates() );
01634 }
01635 
01636 KOEditorRecurrenceDialog::KOEditorRecurrenceDialog(TQWidget * parent)
01637   : KDialogBase( parent, 0, false, i18n("Recurrence"), Ok|Cancel ), mRecurEnabled( false )
01638 {
01639   mRecurrence = new KOEditorRecurrence( this );
01640   setMainWidget( mRecurrence );
01641 }
01642 
01643 void KOEditorRecurrenceDialog::slotOk()
01644 {
01645   mRecurEnabled = mRecurrence->doesRecur();
01646   mRecurrence->saveValues();
01647   emit okClicked(); // tell the incidence editor to update the recurrenceString
01648   accept();
01649 }
01650 
01651 void KOEditorRecurrenceDialog::slotCancel()
01652 {
01653   mRecurrence->setRecurrenceEnabled( mRecurEnabled );
01654   mRecurrence->restoreValues();
01655   reject();
01656 }