summaryrefslogtreecommitdiffstats
path: root/korganizer/koeditorrecurrence.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /korganizer/koeditorrecurrence.cpp
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'korganizer/koeditorrecurrence.cpp')
-rw-r--r--korganizer/koeditorrecurrence.cpp1447
1 files changed, 1447 insertions, 0 deletions
diff --git a/korganizer/koeditorrecurrence.cpp b/korganizer/koeditorrecurrence.cpp
new file mode 100644
index 000000000..48471c421
--- /dev/null
+++ b/korganizer/koeditorrecurrence.cpp
@@ -0,0 +1,1447 @@
+/*
+ This file is part of KOrganizer.
+ Copyright (c) 2000-2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include <qtooltip.h>
+#include <qfiledialog.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qbuttongroup.h>
+#include <qvgroupbox.h>
+#include <qwidgetstack.h>
+#include <qdatetime.h>
+#include <qlistbox.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qwidgetstack.h>
+#include <qradiobutton.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+
+#include <kdialog.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <knumvalidator.h>
+#include <kcalendarsystem.h>
+#include <kmessagebox.h>
+
+#include <libkdepim/kdateedit.h>
+#include <libkcal/todo.h>
+
+#include "koprefs.h"
+#include "koglobals.h"
+
+#include "koeditorrecurrence.h"
+#include "koeditorrecurrence.moc"
+
+/////////////////////////// RecurBase ///////////////////////////////
+
+RecurBase::RecurBase( QWidget *parent, const char *name ) :
+ QWidget( parent, name )
+{
+ mFrequencyEdit = new QSpinBox( 1, 9999, 1, this );
+ mFrequencyEdit->setValue( 1 );
+}
+
+QWidget *RecurBase::frequencyEdit()
+{
+ return mFrequencyEdit;
+}
+
+void RecurBase::setFrequency( int f )
+{
+ if ( f < 1 ) f = 1;
+
+ mFrequencyEdit->setValue( f );
+}
+
+int RecurBase::frequency()
+{
+ return mFrequencyEdit->value();
+}
+
+QComboBox *RecurBase::createWeekCountCombo( QWidget *parent, const char *name )
+{
+ QComboBox *combo = new QComboBox( parent, name );
+ QWhatsThis::add( combo,
+ i18n("The number of the week from the beginning "
+ "of the month on which this event or to-do "
+ "should recur.") );
+ if ( !combo ) return 0;
+ combo->insertItem( i18n("1st") );
+ combo->insertItem( i18n("2nd") );
+ combo->insertItem( i18n("3rd") );
+ combo->insertItem( i18n("4th") );
+ combo->insertItem( i18n("5th") );
+ combo->insertItem( i18n("Last") );
+ combo->insertItem( i18n("2nd Last") );
+ combo->insertItem( i18n("3rd Last") );
+ combo->insertItem( i18n("4th Last") );
+ combo->insertItem( i18n("5th Last") );
+ return combo;
+}
+
+QComboBox *RecurBase::createWeekdayCombo( QWidget *parent, const char *name )
+{
+ QComboBox *combo = new QComboBox( parent, name );
+ QWhatsThis::add( combo,
+ i18n("The weekday on which this event or to-do "
+ "should recur.") );
+ if ( !combo ) return 0;
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+ for( int i = 1; i <= 7; ++i ) {
+ combo->insertItem( calSys->weekDayName( i ) );
+ }
+ return combo;
+}
+
+QComboBox *RecurBase::createMonthNameCombo( QWidget *parent, const char *name )
+{
+ QComboBox *combo = new QComboBox( parent, name );
+ QWhatsThis::add( combo,
+ i18n("The month during which this event or to-do "
+ "should recur.") );
+ if ( !combo ) return 0;
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+ for( int i = 1; i <= 12; ++i ) {
+ // use an arbitrary year, we just need the month name...
+ QDate dt( 2005, i, 1 );
+ combo->insertItem( calSys->monthName( dt ) );
+ }
+ return combo;
+}
+
+QBoxLayout *RecurBase::createFrequencySpinBar( QWidget *parent, QLayout *layout,
+ QString everyText, QString unitText )
+{
+ QBoxLayout *freqLayout = new QHBoxLayout( layout );
+
+ QString whatsThis = i18n("Sets how often this event or to-do should recur.");
+ QLabel *preLabel = new QLabel( everyText, parent );
+ QWhatsThis::add( preLabel, whatsThis );
+ freqLayout->addWidget( preLabel );
+
+ freqLayout->addWidget( frequencyEdit() );
+ preLabel->setBuddy( frequencyEdit() );
+ QWhatsThis::add( preLabel->buddy(), whatsThis );
+
+ QLabel *postLabel = new QLabel( unitText, parent );
+ QWhatsThis::add( postLabel, whatsThis );
+ freqLayout->addWidget( postLabel );
+ freqLayout->addStretch();
+ return freqLayout;
+}
+
+/////////////////////////// RecurDaily ///////////////////////////////
+
+RecurDaily::RecurDaily( QWidget *parent, const char *name ) :
+ RecurBase( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+ topLayout->setSpacing( KDialog::spacingHint() );
+
+ createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("day(s)") );
+}
+
+
+/////////////////////////// RecurWeekly ///////////////////////////////
+
+RecurWeekly::RecurWeekly( QWidget *parent, const char *name ) :
+ RecurBase( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+ topLayout->setSpacing( KDialog::spacingHint() );
+
+// topLayout->addStretch( 1 );
+
+ createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("week(s) on:") );
+
+ QHBox *dayBox = new QHBox( this );
+ topLayout->addWidget( dayBox, 1, AlignVCenter );
+ // Respect start of week setting
+ int weekStart=KGlobal::locale()->weekStartDay();
+ for ( int i = 0; i < 7; ++i ) {
+ // i is the nr of the combobox, not the day of week!
+ // label=(i+weekStart+6)%7 + 1;
+ // index in CheckBox array(=day): label-1
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+ QString weekDayName = calSys->weekDayName(
+ (i + weekStart + 6)%7 + 1, true );
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ weekDayName = weekDayName.left( 1 );
+ }
+ mDayBoxes[ (i + weekStart + 6)%7 ] = new QCheckBox( weekDayName, dayBox );
+ QWhatsThis::add( mDayBoxes[ (i + weekStart + 6)%7 ],
+ i18n("Day of the week on which this event or to-do "
+ "should recur.") );
+ }
+
+ topLayout->addStretch( 1 );
+}
+
+void RecurWeekly::setDays( const QBitArray &days )
+{
+ for ( int i = 0; i < 7; ++i ) {
+ mDayBoxes[ i ]->setChecked( days.testBit( i ) );
+ }
+}
+
+QBitArray RecurWeekly::days()
+{
+ QBitArray days( 7 );
+
+ for ( int i = 0; i < 7; ++i ) {
+ days.setBit( i, mDayBoxes[ i ]->isChecked() );
+ }
+
+ return days;
+}
+
+/////////////////////////// RecurMonthly ///////////////////////////////
+
+RecurMonthly::RecurMonthly( QWidget *parent, const char *name ) :
+ RecurBase( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+ topLayout->setSpacing( KDialog::spacingHint() );
+
+ createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("month(s)") );
+
+ QButtonGroup *buttonGroup = new QButtonGroup( this );
+ buttonGroup->setFrameStyle( QFrame::NoFrame );
+ topLayout->addWidget( buttonGroup, 1, AlignVCenter );
+
+ QGridLayout *buttonLayout = new QGridLayout( buttonGroup, 3, 2 );
+ buttonLayout->setSpacing( KDialog::spacingHint() );
+
+
+ QString recurOnText;
+ if ( !KOPrefs::instance()->mCompactDialogs ) {
+ recurOnText = i18n("&Recur on the");
+ }
+
+ mByDayRadio = new QRadioButton( recurOnText, buttonGroup );
+ QWhatsThis::add( mByDayRadio,
+ i18n("Sets a specific day of the month on which "
+ "this event or to-do should recur.") );
+
+ buttonLayout->addWidget( mByDayRadio, 0, 0 );
+
+ QString whatsThis = i18n("The day of the month on which this event or to-do "
+ "should recur.");
+ mByDayCombo = new QComboBox( buttonGroup );
+ QWhatsThis::add( mByDayCombo, whatsThis );
+ mByDayCombo->setSizeLimit( 7 );
+ mByDayCombo->insertItem( i18n("1st") );
+ mByDayCombo->insertItem( i18n("2nd") );
+ mByDayCombo->insertItem( i18n("3rd") );
+ mByDayCombo->insertItem( i18n("4th") );
+ mByDayCombo->insertItem( i18n("5th") );
+ mByDayCombo->insertItem( i18n("6th") );
+ mByDayCombo->insertItem( i18n("7th") );
+ mByDayCombo->insertItem( i18n("8th") );
+ mByDayCombo->insertItem( i18n("9th") );
+ mByDayCombo->insertItem( i18n("10th") );
+ mByDayCombo->insertItem( i18n("11th") );
+ mByDayCombo->insertItem( i18n("12th") );
+ mByDayCombo->insertItem( i18n("13th") );
+ mByDayCombo->insertItem( i18n("14th") );
+ mByDayCombo->insertItem( i18n("15th") );
+ mByDayCombo->insertItem( i18n("16th") );
+ mByDayCombo->insertItem( i18n("17th") );
+ mByDayCombo->insertItem( i18n("18th") );
+ mByDayCombo->insertItem( i18n("19th") );
+ mByDayCombo->insertItem( i18n("20th") );
+ mByDayCombo->insertItem( i18n("21st") );
+ mByDayCombo->insertItem( i18n("22nd") );
+ mByDayCombo->insertItem( i18n("23rd") );
+ mByDayCombo->insertItem( i18n("24th") );
+ mByDayCombo->insertItem( i18n("25th") );
+ mByDayCombo->insertItem( i18n("26th") );
+ mByDayCombo->insertItem( i18n("27th") );
+ mByDayCombo->insertItem( i18n("28th") );
+ mByDayCombo->insertItem( i18n("29th") );
+ mByDayCombo->insertItem( i18n("30th") );
+ mByDayCombo->insertItem( i18n("31st") );
+ mByDayCombo->insertItem( i18n("Last") );
+ mByDayCombo->insertItem( i18n("2nd Last") );
+ mByDayCombo->insertItem( i18n("3rd Last") );
+ mByDayCombo->insertItem( i18n("4th Last") );
+ mByDayCombo->insertItem( i18n("5th Last") );
+ // FIXME: After the string freeze is over, insert all possible values, not
+ // just the ones we already have translated:
+/* mByDayCombo->insertItem( i18n("6th Last") );
+ mByDayCombo->insertItem( i18n("7th Last") );
+ mByDayCombo->insertItem( i18n("8th Last") );
+ mByDayCombo->insertItem( i18n("9th Last") );
+ mByDayCombo->insertItem( i18n("10th Last") );
+ mByDayCombo->insertItem( i18n("11th Last") );
+ mByDayCombo->insertItem( i18n("12th Last") );
+ mByDayCombo->insertItem( i18n("13th Last") );
+ mByDayCombo->insertItem( i18n("14th Last") );
+ mByDayCombo->insertItem( i18n("15th Last") );
+ mByDayCombo->insertItem( i18n("16th Last") );
+ mByDayCombo->insertItem( i18n("17th Last") );
+ mByDayCombo->insertItem( i18n("18th Last") );
+ mByDayCombo->insertItem( i18n("19th Last") );
+ mByDayCombo->insertItem( i18n("20th Last") );
+ mByDayCombo->insertItem( i18n("21st Last") );
+ mByDayCombo->insertItem( i18n("22nd Last") );
+ mByDayCombo->insertItem( i18n("23rd Last") );
+ mByDayCombo->insertItem( i18n("24th Last") );
+ mByDayCombo->insertItem( i18n("25th Last") );
+ mByDayCombo->insertItem( i18n("26th Last") );
+ mByDayCombo->insertItem( i18n("27th Last") );
+ mByDayCombo->insertItem( i18n("28th Last") );
+ mByDayCombo->insertItem( i18n("29th Last") );
+ mByDayCombo->insertItem( i18n("30th Last") );
+ mByDayCombo->insertItem( i18n("31st Last") );*/
+ buttonLayout->addWidget( mByDayCombo, 0, 1 );
+
+ QLabel *byDayLabel = new QLabel( i18n("day"), buttonGroup );
+ QWhatsThis::add( byDayLabel, whatsThis );
+ buttonLayout->addWidget( byDayLabel, 0, 2 );
+
+
+ mByPosRadio = new QRadioButton( recurOnText, buttonGroup);
+ QWhatsThis::add( mByPosRadio,
+ i18n("Sets a weekday and specific week in the month "
+ "on which this event or to-do should recur") );
+ buttonLayout->addWidget( mByPosRadio, 1, 0 );
+
+ mByPosCountCombo = createWeekCountCombo( buttonGroup );
+ buttonLayout->addWidget( mByPosCountCombo, 1, 1 );
+
+ mByPosWeekdayCombo = createWeekdayCombo( buttonGroup );
+ buttonLayout->addWidget( mByPosWeekdayCombo, 1, 2 );
+}
+
+void RecurMonthly::setByDay( int day )
+{
+ mByDayRadio->setChecked( true );
+ // Days from the end are after the ones from the begin, so correct for the
+ // negative sign and add 30 (index starting at 0)
+ if ( day > 0 && day <= 31 )
+ mByDayCombo->setCurrentItem( day-1 );
+ else if ( day < 0 )
+ mByDayCombo->setCurrentItem( 31 - 1 - day );
+}
+
+void RecurMonthly::setByPos( int count, int weekday )
+{
+ mByPosRadio->setChecked( true );
+ if (count>0)
+ mByPosCountCombo->setCurrentItem( count - 1 );
+ else
+ // negative weeks means counted from the end of month
+ mByPosCountCombo->setCurrentItem( -count + 4 );
+ mByPosWeekdayCombo->setCurrentItem( weekday - 1 );
+}
+
+bool RecurMonthly::byDay()
+{
+ return mByDayRadio->isChecked();
+}
+
+bool RecurMonthly::byPos()
+{
+ return mByPosRadio->isChecked();
+}
+
+int RecurMonthly::day()
+{
+ int day = mByDayCombo->currentItem();
+ if ( day >= 31 ) day = 31-day-1;
+ else ++day;
+ return day;
+}
+
+int RecurMonthly::count()
+{
+ int pos=mByPosCountCombo->currentItem();
+ if (pos<=4) // positive count
+ return pos+1;
+ else
+ return -pos+4;
+}
+
+int RecurMonthly::weekday()
+{
+ return mByPosWeekdayCombo->currentItem() + 1;
+}
+
+/////////////////////////// RecurYearly ///////////////////////////////
+
+RecurYearly::RecurYearly( QWidget *parent, const char *name ) :
+ RecurBase( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+ topLayout->setSpacing( KDialog::spacingHint() );
+
+ createFrequencySpinBar( this, topLayout, i18n("&Recur every"), i18n("year(s)") );
+
+
+ QButtonGroup *buttonGroup = new QButtonGroup( this );
+ buttonGroup->setFrameStyle( QFrame::NoFrame );
+ topLayout->addWidget( buttonGroup, 1, AlignVCenter );
+
+ QBoxLayout *buttonLayout = new QVBoxLayout( buttonGroup );
+
+
+ /* YearlyMonth (day n of Month Y) */
+ QBoxLayout *monthLayout = new QHBoxLayout( buttonLayout );
+ QString recurInMonthText(
+ i18n("part before XXX of 'Recur on day XXX of month YYY'",
+ "&Recur on day "));
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ recurInMonthText = i18n("&Day ");
+ }
+ mByMonthRadio = new QRadioButton( recurInMonthText, buttonGroup );
+ QWhatsThis::add( mByMonthRadio,
+ i18n("Sets a specific day in a specific month on which "
+ "this event or to-do should recur.") );
+ monthLayout->addWidget( mByMonthRadio );
+ mByMonthSpin = new QSpinBox( 1, 31, 1, buttonGroup );
+ QWhatsThis::add( mByMonthSpin,
+ i18n("The day of the month on which this event or to-do "
+ "should recur.") );
+ monthLayout->addWidget( mByMonthSpin );
+ QLabel *ofLabel = new QLabel(
+ i18n("part between XXX and YYY of 'Recur on day XXX of month YYY'", " &of "),
+ buttonGroup );
+ //What do I do here? I'm not sure if this label should have What's This in it... - Antonio
+ monthLayout->addWidget( ofLabel );
+
+ mByMonthCombo = createMonthNameCombo( buttonGroup );
+ monthLayout->addWidget( mByMonthCombo );
+ ofLabel->setBuddy( mByMonthCombo );
+
+ monthLayout->addStretch( 1 );
+
+
+ /* YearlyPos (weekday X of week N of month Y) */
+ QBoxLayout *posLayout = new QHBoxLayout( buttonLayout );
+ QString recurOnPosText( i18n("Part before XXX in 'Recur on NNN. WEEKDAY of MONTH', short version", "&On" ) );
+ if ( !KOPrefs::instance()->mCompactDialogs ) {
+ recurOnPosText = i18n("Part before XXX in 'Recur on NNN. WEEKDAY of MONTH'", "&On the" );
+ }
+ mByPosRadio = new QRadioButton( recurOnPosText, buttonGroup );
+ QWhatsThis::add( mByPosRadio,
+ i18n("Sets a specific day in a specific week of a specific "
+ "month on which this event or to-do should recur.") );
+ posLayout->addWidget( mByPosRadio );
+
+ mByPosDayCombo = createWeekCountCombo( buttonGroup );
+ posLayout->addWidget( mByPosDayCombo );
+
+ mByPosWeekdayCombo = createWeekdayCombo( buttonGroup );
+ posLayout->addWidget( mByPosWeekdayCombo );
+
+ ofLabel = new QLabel(
+ i18n("part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH'", " o&f "),
+ buttonGroup );
+ posLayout->addWidget( ofLabel );
+
+ mByPosMonthCombo = createMonthNameCombo( buttonGroup );
+ posLayout->addWidget( mByPosMonthCombo );
+ ofLabel->setBuddy( mByPosMonthCombo );
+
+ posLayout->addStretch( 1 );
+
+
+ /* YearlyDay (day N of the year) */
+ QBoxLayout *dayLayout = new QHBoxLayout( buttonLayout );
+ QString recurOnDayText;
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ recurOnDayText = i18n("Day #");
+ } else {
+ recurOnDayText = i18n("Recur on &day #");
+ }
+ QString whatsThis = i18n("Sets a specific day within the year on which this "
+ "event or to-do should recur.");
+ mByDayRadio = new QRadioButton( recurOnDayText, buttonGroup );
+ QWhatsThis::add( mByDayRadio, whatsThis );
+ dayLayout->addWidget( mByDayRadio );
+
+ mByDaySpin = new QSpinBox( 1, 366, 1, buttonGroup );
+ QWhatsThis::add( mByDaySpin, whatsThis );
+
+ dayLayout->addWidget( mByDaySpin );
+
+ QString ofTheYear( i18n("part after NNN of 'Recur on day #NNN of the year'", " of the &year"));
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ ofTheYear = i18n("part after NNN of 'Recur on day #NNN of the year', short version",
+ " of the year");
+ }
+ ofLabel = new QLabel( ofTheYear, buttonGroup );
+ QWhatsThis::add( ofLabel, whatsThis );
+ dayLayout->addWidget( ofLabel );
+ ofLabel->setBuddy( mByDaySpin );
+
+ dayLayout->addStretch( 1 );
+}
+
+void RecurYearly::setByDay( int day )
+{
+ mByDayRadio->setChecked( true );
+ mByDaySpin->setValue( day );
+}
+
+void RecurYearly::setByPos( int count, int weekday, int month )
+{
+ mByPosRadio->setChecked( true );
+ if ( count > 0 )
+ mByPosDayCombo->setCurrentItem( count - 1 );
+ else
+ mByPosDayCombo->setCurrentItem( -count + 4 );
+ mByPosWeekdayCombo->setCurrentItem( weekday - 1 );
+ mByPosMonthCombo->setCurrentItem( month-1 );
+}
+
+void RecurYearly::setByMonth( int day, int month )
+{
+ mByMonthRadio->setChecked( true );
+ mByMonthSpin->setValue( day );
+ mByMonthCombo->setCurrentItem( month - 1 );
+}
+
+RecurYearly::YearlyType RecurYearly::getType()
+{
+ if ( mByMonthRadio->isChecked() ) return byMonth;
+ if ( mByPosRadio->isChecked() ) return byPos;
+ if ( mByDayRadio->isChecked() ) return byDay;
+ return byMonth;
+}
+
+int RecurYearly::monthDay()
+{
+ return mByMonthSpin->value();
+}
+
+int RecurYearly::month()
+{
+ return mByMonthCombo->currentItem() + 1;
+}
+
+int RecurYearly::posCount()
+{
+ int pos = mByPosDayCombo->currentItem();
+ if ( pos <= 4 ) // positive count
+ return pos + 1;
+ else
+ return -pos + 4;
+}
+
+int RecurYearly::posWeekday()
+{
+ return mByPosWeekdayCombo->currentItem() + 1;
+}
+
+int RecurYearly::posMonth()
+{
+ return mByPosMonthCombo->currentItem() + 1;
+}
+
+int RecurYearly::day()
+{
+ return mByDaySpin->value();
+}
+
+//////////////////////////// ExceptionsWidget //////////////////////////
+
+ExceptionsWidget::ExceptionsWidget( QWidget *parent, const char *name ) :
+ QWidget( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+
+ QGroupBox *groupBox = new QGroupBox( 1, Horizontal, i18n("E&xceptions"),
+ this );
+ topLayout->addWidget( groupBox );
+
+ QWidget *box = new QWidget( groupBox );
+
+ QGridLayout *boxLayout = new QGridLayout( box );
+
+ mExceptionDateEdit = new KDateEdit( box );
+ QWhatsThis::add( mExceptionDateEdit,
+ i18n("A date that should be considered an exception "
+ "to the recurrence rules for this event or to-do.") );
+ mExceptionDateEdit->setDate( QDate::currentDate() );
+ boxLayout->addWidget( mExceptionDateEdit, 0, 0 );
+
+ QPushButton *addExceptionButton = new QPushButton( i18n("&Add"), box );
+ QWhatsThis::add( addExceptionButton,
+ i18n("Add this date as an exception "
+ "to the recurrence rules for this event or to-do.") );
+ boxLayout->addWidget( addExceptionButton, 1, 0 );
+ QPushButton *changeExceptionButton = new QPushButton( i18n("&Change"), box );
+ QWhatsThis::add( changeExceptionButton,
+ i18n("Replace the currently selected date with this date.") );
+ boxLayout->addWidget( changeExceptionButton, 2, 0 );
+ QPushButton *deleteExceptionButton = new QPushButton( i18n("&Delete"), box );
+ QWhatsThis::add( deleteExceptionButton,
+ i18n("Delete the currently selected date from the list of dates "
+ "that should be considered exceptions to the recurrence rules "
+ "for this event or to-do.") );
+ boxLayout->addWidget( deleteExceptionButton, 3, 0 );
+
+ mExceptionList = new QListBox( box );
+ QWhatsThis::add( mExceptionList,
+ i18n("Displays current dates that are being considered "
+ "exceptions to the recurrence rules for this event "
+ "or to-do.") );
+ boxLayout->addMultiCellWidget( mExceptionList, 0, 3, 1, 1 );
+
+ boxLayout->setRowStretch( 4, 1 );
+ boxLayout->setColStretch( 1, 3 );
+
+ connect( addExceptionButton, SIGNAL( clicked() ),
+ SLOT( addException() ) );
+ connect( changeExceptionButton, SIGNAL( clicked() ),
+ SLOT( changeException() ) );
+ connect( deleteExceptionButton, SIGNAL( clicked() ),
+ SLOT( deleteException() ) );
+}
+
+void ExceptionsWidget::addException()
+{
+ QDate date = mExceptionDateEdit->date();
+ QString dateStr = KGlobal::locale()->formatDate( date );
+ if( !mExceptionList->findItem( dateStr ) ) {
+ mExceptionDates.append( date );
+ mExceptionList->insertItem( dateStr );
+ }
+}
+
+void ExceptionsWidget::changeException()
+{
+ int pos = mExceptionList->currentItem();
+ if ( pos < 0 ) return;
+
+ QDate date = mExceptionDateEdit->date();
+ mExceptionDates[ pos ] = date;
+ mExceptionList->changeItem( KGlobal::locale()->formatDate( date ), pos );
+}
+
+void ExceptionsWidget::deleteException()
+{
+ int pos = mExceptionList->currentItem();
+ if ( pos < 0 ) return;
+
+ mExceptionDates.remove( mExceptionDates.at( pos ) );
+ mExceptionList->removeItem( pos );
+}
+
+void ExceptionsWidget::setDates( const DateList &dates )
+{
+ mExceptionList->clear();
+ mExceptionDates.clear();
+ DateList::ConstIterator dit;
+ for ( dit = dates.begin(); dit != dates.end(); ++dit ) {
+ mExceptionList->insertItem( KGlobal::locale()->formatDate(* dit ) );
+ mExceptionDates.append( *dit );
+ }
+}
+
+DateList ExceptionsWidget::dates()
+{
+ return mExceptionDates;
+}
+
+///////////////////////// ExceptionsDialog ///////////////////////////
+
+ExceptionsDialog::ExceptionsDialog( QWidget *parent, const char *name ) :
+ KDialogBase( parent, name, true, i18n("Edit Exceptions"), Ok|Cancel )
+{
+ mExceptions = new ExceptionsWidget( this );
+ setMainWidget( mExceptions );
+}
+
+void ExceptionsDialog::setDates( const DateList &dates )
+{
+ mExceptions->setDates( dates );
+}
+
+DateList ExceptionsDialog::dates()
+{
+ return mExceptions->dates();
+}
+
+///////////////////////// RecurrenceRangeWidget ///////////////////////////
+
+RecurrenceRangeWidget::RecurrenceRangeWidget( QWidget *parent,
+ const char *name )
+ : QWidget( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+
+ mRangeGroupBox = new QGroupBox( 1, Horizontal, i18n("Recurrence Range"),
+ this );
+ QWhatsThis::add( mRangeGroupBox,
+ i18n("Sets a range for which these recurrence rules will "
+ "apply to this event or to-do.") );
+ topLayout->addWidget( mRangeGroupBox );
+
+ QWidget *rangeBox = new QWidget( mRangeGroupBox );
+ QVBoxLayout *rangeLayout = new QVBoxLayout( rangeBox );
+ rangeLayout->setSpacing( KDialog::spacingHint() );
+
+ mStartDateLabel = new QLabel( i18n("Begin on:"), rangeBox );
+ QWhatsThis::add( mStartDateLabel,
+ i18n("The date on which the recurrences for this event or to-do "
+ "should begin.") );
+ rangeLayout->addWidget( mStartDateLabel );
+
+ QButtonGroup *rangeButtonGroup = new QButtonGroup( this );
+ rangeButtonGroup->hide();
+
+ mNoEndDateButton = new QRadioButton( i18n("&No ending date"), rangeBox );
+ QWhatsThis::add( mNoEndDateButton,
+ i18n("Sets the event or to-do to recur forever.") );
+ rangeButtonGroup->insert( mNoEndDateButton );
+ rangeLayout->addWidget( mNoEndDateButton );
+
+ QBoxLayout *durationLayout = new QHBoxLayout( rangeLayout );
+ durationLayout->setSpacing( KDialog::spacingHint() );
+
+ mEndDurationButton = new QRadioButton( i18n("End &after"), rangeBox );
+ QWhatsThis::add( mEndDurationButton,
+ i18n("Sets the event or to-do to stop recurring after a "
+ "certain number of occurrences.") );
+ rangeButtonGroup->insert( mEndDurationButton );
+ durationLayout->addWidget( mEndDurationButton );
+
+ QString whatsThis = i18n("Number of times the event or to-do should recur "
+ "before stopping.");
+ mEndDurationEdit = new QSpinBox( 1, 9999, 1, rangeBox );
+ QWhatsThis::add( mEndDurationEdit, whatsThis );
+ durationLayout->addWidget( mEndDurationEdit );
+
+ QLabel *endDurationLabel = new QLabel( i18n("&occurrence(s)"), rangeBox );
+ QWhatsThis::add( endDurationLabel, whatsThis );
+ durationLayout ->addWidget( endDurationLabel );
+ endDurationLabel->setBuddy( mEndDurationEdit );
+
+ QBoxLayout *endDateLayout = new QHBoxLayout( rangeLayout );
+ endDateLayout->setSpacing( KDialog::spacingHint() );
+
+ mEndDateButton = new QRadioButton( i18n("End &on:"), rangeBox );
+ QWhatsThis::add( mEndDateButton,
+ i18n("Sets the event or to-do to stop recurring on "
+ "a certain date.") );
+ rangeButtonGroup->insert( mEndDateButton );
+ endDateLayout->addWidget( mEndDateButton );
+
+ mEndDateEdit = new KDateEdit( rangeBox );
+ QWhatsThis::add( mEndDateEdit,
+ i18n("Date after which the event or to-do should stop "
+ "recurring") );
+ endDateLayout->addWidget( mEndDateEdit );
+
+ endDateLayout->addStretch( 1 );
+
+ connect( mNoEndDateButton, SIGNAL( toggled( bool ) ),
+ SLOT( showCurrentRange() ) );
+ connect( mEndDurationButton, SIGNAL( toggled( bool ) ),
+ SLOT( showCurrentRange() ) );
+ connect( mEndDateButton, SIGNAL( toggled( bool ) ),
+ SLOT( showCurrentRange() ) );
+}
+
+void RecurrenceRangeWidget::setDefaults( const QDateTime &from )
+{
+ mNoEndDateButton->setChecked( true );
+
+ setDateTimes( from );
+ setEndDate( from.date() );
+}
+
+void RecurrenceRangeWidget::setDuration( int duration )
+{
+ if ( duration == -1 ) {
+ mNoEndDateButton->setChecked( true );
+ } else if ( duration == 0 ) {
+ mEndDateButton->setChecked( true );
+ } else {
+ mEndDurationButton->setChecked( true );
+ mEndDurationEdit->setValue( duration );
+ }
+}
+
+int RecurrenceRangeWidget::duration()
+{
+ if ( mNoEndDateButton->isChecked() ) {
+ return -1;
+ } else if ( mEndDurationButton->isChecked() ) {
+ return mEndDurationEdit->value();
+ } else {
+ return 0;
+ }
+}
+
+void RecurrenceRangeWidget::setEndDate( const QDate &date )
+{
+ mEndDateEdit->setDate( date );
+}
+
+QDate RecurrenceRangeWidget::endDate()
+{
+ return mEndDateEdit->date();
+}
+
+void RecurrenceRangeWidget::showCurrentRange()
+{
+ mEndDurationEdit->setEnabled( mEndDurationButton->isChecked() );
+ mEndDateEdit->setEnabled( mEndDateButton->isChecked() );
+}
+
+void RecurrenceRangeWidget::setDateTimes( const QDateTime &start,
+ const QDateTime & )
+{
+ mStartDateLabel->setText( i18n("Begins on: %1")
+ .arg( KGlobal::locale()->formatDate( start.date() ) ) );
+}
+
+///////////////////////// RecurrenceRangeDialog ///////////////////////////
+
+RecurrenceRangeDialog::RecurrenceRangeDialog( QWidget *parent,
+ const char *name ) :
+ KDialogBase( parent, name, true, i18n("Edit Recurrence Range"), Ok|Cancel )
+{
+ mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
+ setMainWidget( mRecurrenceRangeWidget );
+}
+
+void RecurrenceRangeDialog::setDefaults( const QDateTime &from )
+{
+ mRecurrenceRangeWidget->setDefaults( from );
+}
+
+void RecurrenceRangeDialog::setDuration( int duration )
+{
+ mRecurrenceRangeWidget->setDuration( duration );
+}
+
+int RecurrenceRangeDialog::duration()
+{
+ return mRecurrenceRangeWidget->duration();
+}
+
+void RecurrenceRangeDialog::setEndDate( const QDate &date )
+{
+ mRecurrenceRangeWidget->setEndDate( date );
+}
+
+QDate RecurrenceRangeDialog::endDate()
+{
+ return mRecurrenceRangeWidget->endDate();
+}
+
+void RecurrenceRangeDialog::setDateTimes( const QDateTime &start,
+ const QDateTime &end )
+{
+ mRecurrenceRangeWidget->setDateTimes( start, end );
+}
+
+//////////////////////////// RecurrenceChooser ////////////////////////
+
+RecurrenceChooser::RecurrenceChooser( QWidget *parent, const char *name ) :
+ QWidget( parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ mTypeCombo = new QComboBox( this );
+ QWhatsThis::add( mTypeCombo,
+ i18n("Sets the type of recurrence this event or to-do "
+ "should have.") );
+ mTypeCombo->insertItem( i18n("Daily") );
+ mTypeCombo->insertItem( i18n("Weekly") );
+ mTypeCombo->insertItem( i18n("Monthly") );
+ mTypeCombo->insertItem( i18n("Yearly") );
+
+ topLayout->addWidget( mTypeCombo );
+
+ connect( mTypeCombo, SIGNAL( activated( int ) ), SLOT( emitChoice() ) );
+ } else {
+ mTypeCombo = 0;
+
+ QButtonGroup *ruleButtonGroup = new QButtonGroup( 1, Horizontal, this );
+ ruleButtonGroup->setFrameStyle( QFrame::NoFrame );
+ topLayout->addWidget( ruleButtonGroup );
+
+ mDailyButton = new QRadioButton( i18n("&Daily"), ruleButtonGroup );
+ QWhatsThis::add( mDailyButton,
+ i18n("Sets the event or to-do to recur daily according "
+ "to the specified rules.") );
+ mWeeklyButton = new QRadioButton( i18n("&Weekly"), ruleButtonGroup );
+ QWhatsThis::add( mWeeklyButton,
+ i18n("Sets the event or to-do to recur weekly according "
+ "to the specified rules.") );
+ mMonthlyButton = new QRadioButton( i18n("&Monthly"), ruleButtonGroup );
+ QWhatsThis::add( mMonthlyButton,
+ i18n("Sets the event or to-do to recur monthly according "
+ "to the specified rules.") );
+ mYearlyButton = new QRadioButton( i18n("&Yearly"), ruleButtonGroup );
+ QWhatsThis::add( mYearlyButton,
+ i18n("Sets the event or to-do to recur yearly according "
+ "to the specified rules.") );
+
+ connect( mDailyButton, SIGNAL( toggled( bool ) ),
+ SLOT( emitChoice() ) );
+ connect( mWeeklyButton, SIGNAL( toggled( bool ) ),
+ SLOT( emitChoice() ) );
+ connect( mMonthlyButton, SIGNAL( toggled( bool ) ),
+ SLOT( emitChoice() ) );
+ connect( mYearlyButton, SIGNAL( toggled( bool ) ),
+ SLOT( emitChoice() ) );
+ }
+}
+
+int RecurrenceChooser::type()
+{
+ if ( mTypeCombo ) {
+ return mTypeCombo->currentItem();
+ } else {
+ if ( mDailyButton->isChecked() ) return Daily;
+ else if ( mWeeklyButton->isChecked() ) return Weekly;
+ else if ( mMonthlyButton->isChecked() ) return Monthly;
+ else return Yearly;
+ }
+}
+
+void RecurrenceChooser::setType( int type )
+{
+ if ( mTypeCombo ) {
+ mTypeCombo->setCurrentItem( type );
+ } else {
+ switch ( type ) {
+ case Daily:
+ mDailyButton->setChecked( true );
+ break;
+ case Weekly:
+ mWeeklyButton->setChecked( true );
+ break;
+ case Monthly:
+ mMonthlyButton->setChecked( true );
+ break;
+ case Yearly:
+ default:
+ mYearlyButton->setChecked( true );
+ break;
+ }
+ }
+}
+
+void RecurrenceChooser::emitChoice()
+{
+ emit chosen ( type() );
+}
+
+/////////////////////////////// Main Widget /////////////////////////////
+
+KOEditorRecurrence::KOEditorRecurrence( QWidget* parent, const char *name ) :
+ QWidget( parent, name )
+{
+ QGridLayout *topLayout = new QGridLayout( this );
+ topLayout->setSpacing( KDialog::spacingHint() );
+
+ mEnabledCheck = new QCheckBox( i18n("&Enable recurrence"), this );
+ QWhatsThis::add( mEnabledCheck,
+ i18n("Enables recurrence for this event or to-do according "
+ "to the specified rules.") );
+ connect( mEnabledCheck, SIGNAL( toggled( bool ) ),
+ SLOT( setRecurrenceEnabled( bool ) ) );
+ topLayout->addMultiCellWidget( mEnabledCheck, 0, 0, 0, 1 );
+
+
+ mTimeGroupBox = new QGroupBox( 1, Horizontal, i18n("Appointment Time "),
+ this );
+ QWhatsThis::add( mTimeGroupBox,
+ i18n("Displays appointment time information.") );
+ topLayout->addMultiCellWidget( mTimeGroupBox, 1, 1 , 0 , 1 );
+
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ mTimeGroupBox->hide();
+ }
+
+// QFrame *timeFrame = new QFrame( mTimeGroupBox );
+// QBoxLayout *layoutTimeFrame = new QHBoxLayout( timeFrame );
+// layoutTimeFrame->setSpacing( KDialog::spacingHint() );
+
+ mDateTimeLabel = new QLabel( mTimeGroupBox );
+// mDateTimeLabel = new QLabel( timeFrame );
+// layoutTimeFrame->addWidget( mDateTimeLabel );
+
+ Qt::Orientation orientation;
+ if ( KOPrefs::instance()->mCompactDialogs ) orientation = Horizontal;
+ else orientation = Vertical;
+
+ mRuleBox = new QGroupBox( 1, orientation, i18n("Recurrence Rule"), this );
+ QWhatsThis::add( mRuleBox,
+ i18n("Options concerning the type of recurrence this event "
+ "or to-do should have.") );
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ topLayout->addWidget( mRuleBox, 2, 0 );
+ } else {
+ topLayout->addMultiCellWidget( mRuleBox, 2, 2, 0, 1 );
+ }
+
+ mRecurrenceChooser = new RecurrenceChooser( mRuleBox );
+ connect( mRecurrenceChooser, SIGNAL( chosen( int ) ),
+ SLOT( showCurrentRule( int ) ) );
+
+ if ( !KOPrefs::instance()->mCompactDialogs ) {
+ QFrame *ruleSepFrame = new QFrame( mRuleBox );
+ ruleSepFrame->setFrameStyle( QFrame::VLine | QFrame::Sunken );
+ }
+
+ mRuleStack = new QWidgetStack( mRuleBox );
+
+ mDaily = new RecurDaily( mRuleStack );
+ mRuleStack->addWidget( mDaily, 0 );
+
+ mWeekly = new RecurWeekly( mRuleStack );
+ mRuleStack->addWidget( mWeekly, 0 );
+
+ mMonthly = new RecurMonthly( mRuleStack );
+ mRuleStack->addWidget( mMonthly, 0 );
+
+ mYearly = new RecurYearly( mRuleStack );
+ mRuleStack->addWidget( mYearly, 0 );
+
+ showCurrentRule( mRecurrenceChooser->type() );
+
+ if ( KOPrefs::instance()->mCompactDialogs ) {
+ mRecurrenceRangeWidget = 0;
+ mRecurrenceRangeDialog = new RecurrenceRangeDialog( this );
+ mRecurrenceRange = mRecurrenceRangeDialog;
+ mRecurrenceRangeButton = new QPushButton( i18n("Recurrence Range..."),
+ this );
+ QWhatsThis::add( mRecurrenceRangeButton,
+ i18n("Options concerning the time range during which "
+ "this event or to-do should recur.") );
+ topLayout->addWidget( mRecurrenceRangeButton, 3, 0 );
+ connect( mRecurrenceRangeButton, SIGNAL( clicked() ),
+ SLOT( showRecurrenceRangeDialog() ) );
+
+ mExceptionsWidget = 0;
+ mExceptionsDialog = new ExceptionsDialog( this );
+ mExceptions = mExceptionsDialog;
+ mExceptionsButton = new QPushButton( i18n("Exceptions..."), this );
+ topLayout->addWidget( mExceptionsButton, 4, 0 );
+ connect( mExceptionsButton, SIGNAL( clicked() ),
+ SLOT( showExceptionsDialog() ) );
+
+ } else {
+ mRecurrenceRangeWidget = new RecurrenceRangeWidget( this );
+ QWhatsThis::add( mRecurrenceRangeWidget,
+ i18n("Options concerning the time range during which "
+ "this event or to-do should recur.") );
+ mRecurrenceRangeDialog = 0;
+ mRecurrenceRange = mRecurrenceRangeWidget;
+ mRecurrenceRangeButton = 0;
+ topLayout->addWidget( mRecurrenceRangeWidget, 3, 0 );
+
+ mExceptionsWidget = new ExceptionsWidget( this );
+ mExceptionsDialog = 0;
+ mExceptions = mExceptionsWidget;
+ mExceptionsButton = 0;
+ topLayout->addWidget( mExceptionsWidget, 3, 1 );
+ }
+}
+
+KOEditorRecurrence::~KOEditorRecurrence()
+{
+}
+
+void KOEditorRecurrence::setRecurrenceEnabled( bool enabled )
+{
+// kdDebug(5850) << "KOEditorRecurrence::setRecurrenceEnabled(): " << (enabled ? "on" : "off") << endl;
+
+ mTimeGroupBox->setEnabled( enabled );
+ mRuleBox->setEnabled( enabled );
+ if ( mRecurrenceRangeWidget ) mRecurrenceRangeWidget->setEnabled( enabled );
+ if ( mRecurrenceRangeButton ) mRecurrenceRangeButton->setEnabled( enabled );
+ if ( mExceptionsWidget ) mExceptionsWidget->setEnabled( enabled );
+ if ( mExceptionsButton ) mExceptionsButton->setEnabled( enabled );
+}
+
+void KOEditorRecurrence::showCurrentRule( int current )
+{
+ switch ( current ) {
+ case Daily:
+ mRuleStack->raiseWidget( mDaily );
+ break;
+ case Weekly:
+ mRuleStack->raiseWidget( mWeekly );
+ break;
+ case Monthly:
+ mRuleStack->raiseWidget( mMonthly );
+ break;
+ default:
+ case Yearly:
+ mRuleStack->raiseWidget( mYearly );
+ break;
+ }
+}
+
+void KOEditorRecurrence::setDateTimes( const QDateTime &start, const QDateTime &end )
+{
+// kdDebug(5850) << "KOEditorRecurrence::setDateTimes" << endl;
+
+ mEventStartDt = start;
+ mRecurrenceRange->setDateTimes( start, end );
+ mDaily->setDateTimes( start, end );
+ mWeekly->setDateTimes( start, end );
+ mMonthly->setDateTimes( start, end );
+ mYearly->setDateTimes( start, end );
+
+ // Now set the defaults for all unused types, use the start time for it
+ bool enabled = mEnabledCheck->isChecked();
+ int type = mRecurrenceChooser->type();
+
+ if ( !enabled || type != RecurrenceChooser::Weekly ) {
+ QBitArray days( 7 );
+ days.fill( 0 );
+ days.setBit( (start.date().dayOfWeek()+6) % 7 );
+ mWeekly->setDays( days );
+ }
+ if ( !enabled || type != RecurrenceChooser::Monthly ) {
+ mMonthly->setByPos( ( start.date().day() - 1 ) / 7 + 1, start.date().dayOfWeek() - 1 );
+ mMonthly->setByDay( start.date().day() );
+ }
+ if ( !enabled || type != RecurrenceChooser::Yearly ) {
+ mYearly->setByDay( start.date().dayOfYear() );
+ mYearly->setByPos( ( start.date().day() - 1 ) / 7 + 1,
+ start.date().dayOfWeek() - 1, start.date().month() );
+ mYearly->setByMonth( start.date().day(), start.date().month() );
+ }
+}
+
+void KOEditorRecurrence::setDefaults( const QDateTime &from, const QDateTime &to, bool )
+{
+ setDateTimes( from, to );
+
+ bool enabled = false;
+ mEnabledCheck->setChecked( enabled );
+ setRecurrenceEnabled( enabled );
+
+ mRecurrenceRange->setDefaults( from );
+
+ mRecurrenceChooser->setType( RecurrenceChooser::Weekly );
+ showCurrentRule( mRecurrenceChooser->type() );
+
+ mDaily->setFrequency( 1 );
+
+ mWeekly->setFrequency( 1 );
+ QBitArray days( 7 );
+ days.fill( 0 );
+ days.setBit( (from.date().dayOfWeek()+6) % 7 );
+ mWeekly->setDays( days );
+
+ mMonthly->setFrequency( 1 );
+ mMonthly->setByPos( ( from.date().day() - 1 ) / 7 + 1, from.date().dayOfWeek() );
+ mMonthly->setByDay( from.date().day() );
+
+ mYearly->setFrequency( 1 );
+ mYearly->setByDay( from.date().dayOfYear() );
+ mYearly->setByPos( ( from.date().day() - 1 ) / 7 + 1,
+ from.date().dayOfWeek(), from.date().month() );
+ mYearly->setByMonth( from.date().day(), from.date().month() );
+}
+
+void KOEditorRecurrence::readIncidence(Incidence *incidence)
+{
+ if (!incidence) return;
+
+ QBitArray rDays( 7 );
+ int day = 0;
+ int count = 0;
+ int month = 0;
+
+ if ( incidence->type() == "Todo" ) {
+ Todo *todo = static_cast<Todo *>(incidence);
+ setDefaults( todo->dtStart(true), todo->dtDue(), todo->doesFloat() );
+ } else {
+ setDefaults( incidence->dtStart(), incidence->dtEnd(), incidence->doesFloat() );
+ }
+
+ uint recurs = incidence->recurrenceType();
+ int f = 0;
+ Recurrence *r = 0;
+
+ if ( recurs ) {
+ r = incidence->recurrence();
+ f = r->frequency();
+ }
+
+
+ mEnabledCheck->setChecked( recurs );
+ setRecurrenceEnabled( recurs );
+
+ int recurrenceType = RecurrenceChooser::Weekly;
+
+ switch ( recurs ) {
+ case Recurrence::rNone:
+ break;
+ case Recurrence::rDaily:
+ recurrenceType = RecurrenceChooser::Daily;
+ mDaily->setFrequency( f );
+ break;
+ case Recurrence::rWeekly:
+ recurrenceType = RecurrenceChooser::Weekly;
+ mWeekly->setFrequency( f );
+ mWeekly->setDays( r->days() );
+ break;
+ case Recurrence::rMonthlyPos: {
+ // TODO: we only handle one possibility in the list right now,
+ // so I have hardcoded calls with first(). If we make the GUI
+ // more extended, this can be changed.
+ recurrenceType = RecurrenceChooser::Monthly;
+
+ QValueList<RecurrenceRule::WDayPos> rmp = r->monthPositions();
+ if ( !rmp.isEmpty() ) {
+ mMonthly->setByPos( rmp.first().pos(), rmp.first().day() );
+ }
+
+ mMonthly->setFrequency( f );
+
+ break; }
+ case Recurrence::rMonthlyDay: {
+ recurrenceType = RecurrenceChooser::Monthly;
+
+ QValueList<int> rmd = r->monthDays();
+ // check if we have any setting for which day (vcs import is broken and
+ // does not set any day, thus we need to check)
+ if ( rmd.isEmpty() ) {
+ day = incidence->dtStart().date().day();
+ } else {
+ day = rmd.first();
+ }
+ mMonthly->setByDay( day );
+
+ mMonthly->setFrequency( f );
+
+ break; }
+ case Recurrence::rYearlyMonth: {
+ recurrenceType = RecurrenceChooser::Yearly;
+ QValueList<int> rmd = r->yearDates();
+ if ( rmd.isEmpty() ) {
+ day = incidence->dtStart().date().day();
+ } else {
+ day = rmd.first();
+ }
+ int month = incidence->dtStart().date().month();
+ rmd = r->yearMonths();
+ if ( !rmd.isEmpty() )
+ month = rmd.first();
+ mYearly->setByMonth( day, month );
+ mYearly->setFrequency( f );
+ break; }
+ case Recurrence::rYearlyPos: {
+ recurrenceType = RecurrenceChooser::Yearly;
+
+ QValueList<int> months = r->yearMonths();
+ if ( months.isEmpty() ) {
+ month = incidence->dtStart().date().month();
+ } else {
+ month = months.first();
+ }
+
+ QValueList<RecurrenceRule::WDayPos> pos = r->yearPositions();
+
+ if ( pos.isEmpty() ) {
+ // Use dtStart if nothing is given (shouldn't happen!)
+ count = ( incidence->dtStart().date().day() - 1 ) / 7;
+ day = incidence->dtStart().date().dayOfWeek();
+ } else {
+ count = pos.first().pos();
+ day = pos.first().day();
+ }
+ mYearly->setByPos( count, day, month );
+ mYearly->setFrequency( f );
+ break; }
+ case Recurrence::rYearlyDay: {
+ recurrenceType = RecurrenceChooser::Yearly;
+ QValueList<int> days = r->yearDays();
+ if ( days.isEmpty() ) {
+ day = incidence->dtStart().date().dayOfYear();
+ } else {
+ day = days.first();
+ }
+ mYearly->setByDay( day );
+
+ mYearly->setFrequency( f );
+ break; }
+ default:
+ break;
+ }
+
+ mRecurrenceChooser->setType( recurrenceType );
+ showCurrentRule( recurrenceType );
+
+ mRecurrenceRange->setDateTimes( incidence->recurrence()->startDateTime() );
+
+ if ( incidence->doesRecur() ) {
+ mRecurrenceRange->setDuration( r->duration() );
+ if ( r->duration() == 0 ) mRecurrenceRange->setEndDate( r->endDate() );
+ }
+
+ mExceptions->setDates( incidence->recurrence()->exDates() );
+}
+
+void KOEditorRecurrence::writeIncidence( Incidence *incidence )
+{
+ if ( !mEnabledCheck->isChecked() || !isEnabled() )
+ {
+ if ( incidence->doesRecur() )
+ incidence->recurrence()->unsetRecurs();
+ return;
+ }
+
+ Recurrence *r = incidence->recurrence();
+
+ // clear out any old settings;
+ r->unsetRecurs();
+
+ int duration = mRecurrenceRange->duration();
+ QDate endDate;
+ if ( duration == 0 ) endDate = mRecurrenceRange->endDate();
+
+ int recurrenceType = mRecurrenceChooser->type();
+ if ( recurrenceType == RecurrenceChooser::Daily ) {
+ r->setDaily( mDaily->frequency() );
+ } else if ( recurrenceType == RecurrenceChooser::Weekly ) {
+ r->setWeekly( mWeekly->frequency(), mWeekly->days() );
+ } else if ( recurrenceType == RecurrenceChooser::Monthly ) {
+ r->setMonthly( mMonthly->frequency() );
+
+ if ( mMonthly->byPos() ) {
+ int pos = mMonthly->count();
+
+ QBitArray days( 7 );
+ days.fill( false );
+ days.setBit( mMonthly->weekday() - 1 );
+ r->addMonthlyPos( pos, days );
+ } else {
+ // it's by day
+ r->addMonthlyDate( mMonthly->day() );
+ }
+ } else if ( recurrenceType == RecurrenceChooser::Yearly ) {
+ r->setYearly( mYearly->frequency() );
+
+ switch ( mYearly->getType() ) {
+ case RecurYearly::byMonth:
+ r->addYearlyDate( mYearly->monthDay() );
+ r->addYearlyMonth( mYearly->month() );
+ break;
+ case RecurYearly::byPos: {
+ r->addYearlyMonth( mYearly->posMonth() );
+ QBitArray days( 7 );
+ days.fill( false );
+ days.setBit( mYearly->posWeekday() - 1 );
+ r->addYearlyPos( mYearly->posCount(), days );
+ break; }
+ case RecurYearly::byDay:
+ r->addYearlyDay( mYearly->day() );
+ break;
+ }
+ } // end "Yearly"
+
+ if ( duration > 0 )
+ r->setDuration( duration );
+ else if ( duration == 0 )
+ r->setEndDate( endDate );
+ incidence->recurrence()->setExDates( mExceptions->dates() );
+}
+
+void KOEditorRecurrence::setDateTimeStr( const QString &str )
+{
+ mDateTimeLabel->setText( str );
+}
+
+bool KOEditorRecurrence::validateInput()
+{
+ // Check input here.
+ // Check if the recurrence (if set to end at a date) is scheduled to end before the event starts.
+ if ( mEnabledCheck->isChecked() && (mRecurrenceRange->duration()==0) &&
+ mEventStartDt.isValid() && ((mRecurrenceRange->endDate())<mEventStartDt.date()) ) {
+ KMessageBox::sorry( 0,
+ i18n("The end date '%1' of the recurrence must be after the start date '%2' of the event.")
+ .arg( KGlobal::locale()->formatDate( mRecurrenceRange->endDate() ) )
+ .arg( KGlobal::locale()->formatDate( mEventStartDt.date() ) ) );
+ return false;
+ }
+ int recurrenceType = mRecurrenceChooser->type();
+ // Check if a weekly recurrence has at least one day selected
+ // TODO: Get rid of this, it's not really needed (by default the day should be taken from dtStart)
+ if( mEnabledCheck->isChecked() && recurrenceType == RecurrenceChooser::Weekly ) {
+ const QBitArray &days = mWeekly->days();
+ bool valid = false;
+ for ( int i=0; i<7; ++i ) valid = valid || days.testBit( i );
+ if ( !valid ) {
+ KMessageBox::sorry( 0,
+ i18n("A weekly recurring event or task has to have at least one weekday "
+ "associated with it.") );
+ return false;
+ }
+ }
+ return true;
+}
+
+void KOEditorRecurrence::showExceptionsDialog()
+{
+ DateList dates = mExceptions->dates();
+ int result = mExceptionsDialog->exec();
+ if ( result == QDialog::Rejected ) mExceptions->setDates( dates );
+}
+
+void KOEditorRecurrence::showRecurrenceRangeDialog()
+{
+ int duration = mRecurrenceRange->duration();
+ QDate endDate = mRecurrenceRange->endDate();
+
+ int result = mRecurrenceRangeDialog->exec();
+ if ( result == QDialog::Rejected ) {
+ mRecurrenceRange->setDuration( duration );
+ mRecurrenceRange->setEndDate( endDate );
+ }
+}
+
+bool KOEditorRecurrence::doesRecur()
+{
+ return mEnabledCheck->isChecked();
+}
+
+
+KOEditorRecurrenceDialog::KOEditorRecurrenceDialog(QWidget * parent) :
+ KDialogBase( parent, 0, false, i18n("Recurrence"), Ok )
+{
+ mRecurrence = new KOEditorRecurrence( this );
+ setMainWidget( mRecurrence );
+}