korganizer

koeditoralarms.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
00024 */
00025 
00026 #include "koeditoralarms_base.h"
00027 #include "koeditoralarms.h"
00028 
00029 #include <qlayout.h>
00030 #include <qlistview.h>
00031 #include <qpushbutton.h>
00032 #include <qspinbox.h>
00033 #include <qcombobox.h>
00034 #include <qcheckbox.h>
00035 #include <qbuttongroup.h>
00036 #include <qtextedit.h>
00037 #include <qwidgetstack.h>
00038 #include <qradiobutton.h>
00039 
00040 #include <kurlrequester.h>
00041 #include <klocale.h>
00042 #include <kdebug.h>
00043 
00044 #include <libkcal/alarm.h>
00045 #include <libkcal/incidence.h>
00046 
00047 #include <libemailfunctions/email.h>
00048 
00049 class AlarmListViewItem : public QListViewItem
00050 {
00051   public:
00052     AlarmListViewItem( QListView *parent, KCal::Alarm *alarm );
00053     virtual ~AlarmListViewItem();
00054     KCal::Alarm *alarm() const { return mAlarm; }
00055     void construct();
00056     enum AlarmViewColumns { ColAlarmType=0, ColAlarmOffset, ColAlarmRepeat };
00057   protected:
00058     KCal::Alarm *mAlarm;
00059 };
00060 
00061 AlarmListViewItem::AlarmListViewItem( QListView *parent, KCal::Alarm *alarm )
00062     : QListViewItem( parent )
00063 {
00064   if ( alarm ) {
00065     mAlarm = new KCal::Alarm( *alarm );
00066   } else {
00067     mAlarm = new KCal::Alarm( 0 );
00068   }
00069   construct();
00070 }
00071 
00072 AlarmListViewItem::~AlarmListViewItem()
00073 {
00074   delete mAlarm;
00075 }
00076 
00077 void AlarmListViewItem::construct()
00078 {
00079   if ( mAlarm ) {
00080     // Alarm type:
00081     QString type;
00082     switch ( mAlarm->type() ) {
00083       case KCal::Alarm::Display:
00084         type = i18n("Reminder Dialog");
00085         break;
00086       case KCal::Alarm::Procedure:
00087         type = i18n("Program");
00088         break;
00089       case KCal::Alarm::Email:
00090         type = i18n("Email");
00091         break;
00092       case KCal::Alarm::Audio:
00093         type = i18n("Audio");
00094         break;
00095       default:
00096         type = i18n("Unknown");
00097         break;
00098     }
00099     setText( ColAlarmType, type );
00100 
00101     // Alarm offset:
00102     QString offsetstr;
00103     int offset = 0;
00104     if ( mAlarm->hasStartOffset() ) {
00105       offset = mAlarm->startOffset().asSeconds();
00106       if ( offset < 0 ) {
00107         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the start");
00108         offset = -offset;
00109       } else {
00110         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the start");
00111       }
00112     } else if ( mAlarm->hasEndOffset() ) {
00113       offset = mAlarm->endOffset().asSeconds();
00114       if ( offset < 0 ) {
00115         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the end");
00116         offset = -offset;
00117       } else {
00118         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the end");
00119       }
00120     }
00121 
00122     offset = offset / 60; // make minutes
00123     int useoffset = offset;
00124 
00125     if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days?
00126       useoffset = offset / (24*60);
00127       offsetstr = offsetstr.arg( i18n("1 day", "%n days", useoffset ) );
00128     } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours?
00129       useoffset = offset / 60;
00130       offsetstr = offsetstr.arg( i18n("1 hour", "%n hours", useoffset ) );
00131     } else {
00132       useoffset = offset;
00133       offsetstr = offsetstr.arg( i18n("1 minute", "%n minutes", useoffset ) );
00134     }
00135     setText( ColAlarmOffset, offsetstr );
00136 
00137     // Alarm repeat
00138     if ( mAlarm->repeatCount()>0 ) {
00139       setText( ColAlarmRepeat, i18n("Yes") );
00140     } else {
00141       setText( ColAlarmRepeat, i18n("No") );
00142     }
00143   }
00144 }
00145 
00146 
00147 KOEditorAlarms::KOEditorAlarms( KCal::Alarm::List *alarms, QWidget *parent,
00148                                 const char *name )
00149   : KDialogBase( parent, name, true, i18n("Edit Reminders"), Ok | Cancel ), mAlarms( alarms ),mCurrentItem(0L)
00150 {
00151   setMainWidget( mWidget = new KOEditorAlarms_base( this ) );
00152   mWidget->mAlarmList->setColumnWidthMode( 0, QListView::Maximum );
00153   mWidget->mAlarmList->setColumnWidthMode( 1, QListView::Maximum );
00154   connect( mWidget->mAlarmList, SIGNAL( selectionChanged( QListViewItem * ) ),
00155            SLOT( selectionChanged( QListViewItem * ) ) );
00156   connect( mWidget->mAddButton, SIGNAL( clicked() ), SLOT( slotAdd() ) );
00157   connect( mWidget->mRemoveButton, SIGNAL( clicked() ), SLOT( slotRemove() ) );
00158   connect( mWidget->mDuplicateButton, SIGNAL( clicked() ), SLOT( slotDuplicate() ) );
00159 
00160   connect( mWidget->mAlarmOffset, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00161   connect( mWidget->mOffsetUnit, SIGNAL( activated( int ) ), SLOT( changed() ) );
00162   connect( mWidget->mBeforeAfter, SIGNAL( activated( int ) ), SLOT( changed() ) );
00163   connect( mWidget->mRepeats, SIGNAL( toggled( bool ) ), SLOT( changed() ) );
00164   connect( mWidget->mRepeatCount, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00165   connect( mWidget->mRepeatInterval, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00166   connect( mWidget->mAlarmType, SIGNAL(clicked(int)), SLOT( changed() ) );
00167   connect( mWidget->mDisplayText, SIGNAL( textChanged() ), SLOT( changed() ) );
00168   connect( mWidget->mSoundFile, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00169   connect( mWidget->mApplication, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00170   connect( mWidget->mAppArguments, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00171   connect( mWidget->mEmailAddress, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00172   connect( mWidget->mEmailText, SIGNAL( textChanged() ), SLOT( changed() ) );
00173 
00174   init();
00175   mWidget->mTypeEmailRadio->hide();
00176 }
00177 
00178 KOEditorAlarms::~KOEditorAlarms()
00179 {
00180 }
00181 
00182 void KOEditorAlarms::changed()
00183 {
00184   if ( !mInitializing && mCurrentItem ) {
00185     writeAlarm( mCurrentItem->alarm() );
00186     mCurrentItem->construct();
00187   }
00188 }
00189 
00190 void KOEditorAlarms::readAlarm( KCal::Alarm *alarm )
00191 {
00192   if ( !alarm ) return;
00193 
00194   mInitializing = true;
00195 
00196   // Offsets
00197   int offset;
00198   int beforeafterpos = 0;
00199   if ( alarm->hasEndOffset() ) {
00200     beforeafterpos = 2;
00201     offset = alarm->endOffset().asSeconds();
00202   } else {
00203     // TODO: Also allow alarms at fixed times, not relative to start/end
00204     offset = alarm->startOffset().asSeconds();
00205   }
00206   // Negative offset means before the start/end...
00207   if ( offset < 0 ) {
00208     offset = -offset;
00209   } else {
00210     ++beforeafterpos;
00211   }
00212   mWidget->mBeforeAfter->setCurrentItem( beforeafterpos );
00213 
00214   offset = offset / 60; // make minutes
00215   int useoffset = offset;
00216 
00217   if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days?
00218     useoffset = offset / (24*60);
00219     mWidget->mOffsetUnit->setCurrentItem( 2 );
00220   } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours?
00221     useoffset = offset / 60;
00222     mWidget->mOffsetUnit->setCurrentItem( 1 );
00223   } else {
00224     useoffset = offset;
00225     mWidget->mOffsetUnit->setCurrentItem( 0 );
00226   }
00227   mWidget->mAlarmOffset->setValue( useoffset );
00228 
00229 
00230   // Repeating
00231   mWidget->mRepeats->setChecked( alarm->repeatCount()>0 );
00232   if ( alarm->repeatCount()>0 ) {
00233     mWidget->mRepeatCount->setValue( alarm->repeatCount() );
00234     mWidget->mRepeatInterval->setValue( alarm->snoozeTime() );
00235   }
00236 
00237   switch ( alarm->type() ) {
00238     case KCal::Alarm::Audio:
00239         mWidget->mAlarmType->setButton( 1 );
00240         mWidget->mSoundFile->setURL( alarm->audioFile() );
00241         break;
00242     case KCal::Alarm::Procedure:
00243         mWidget->mAlarmType->setButton( 2 );
00244         mWidget->mApplication->setURL( alarm->programFile() );
00245         mWidget->mAppArguments->setText( alarm->programArguments() );
00246         break;
00247     case KCal::Alarm::Email: {
00248         mWidget->mAlarmType->setButton( 3 );
00249         QValueList<KCal::Person> addresses = alarm->mailAddresses();
00250         QStringList add;
00251         for ( QValueList<KCal::Person>::ConstIterator it = addresses.begin();
00252               it != addresses.end(); ++it ) {
00253           add << (*it).fullName();
00254         }
00255         mWidget->mEmailAddress->setText( add.join(", ") );
00256         mWidget->mEmailText->setText( alarm->mailText() );
00257         break;}
00258     case KCal::Alarm::Display:
00259     case KCal::Alarm::Invalid:
00260     default:
00261         mWidget->mAlarmType->setButton( 0 );
00262         mWidget->mDisplayText->setText( alarm->text() );
00263         break;
00264   }
00265 
00266   mWidget->mTypeStack->raiseWidget( mWidget->mAlarmType->selectedId() );
00267 
00268   mInitializing = false;
00269 }
00270 
00271 void KOEditorAlarms::writeAlarm( KCal::Alarm *alarm )
00272 {
00273   // Offsets
00274   int offset = mWidget->mAlarmOffset->value()*60; // minutes
00275   int offsetunit = mWidget->mOffsetUnit->currentItem();
00276   if ( offsetunit >= 1 ) offset *= 60; // hours
00277   if ( offsetunit >= 2 ) offset *= 24; // days
00278   if ( offsetunit >= 3 ) offset *= 7; // weeks
00279 
00280   int beforeafterpos = mWidget->mBeforeAfter->currentItem();
00281   if ( beforeafterpos % 2 == 0 ) { // before -> negative
00282     offset = -offset;
00283   }
00284 
00285   // TODO: Add possibility to specify a given time for the reminder
00286   if ( beforeafterpos / 2 == 0 ) { // start offset
00287     alarm->setStartOffset( KCal::Duration( offset ) );
00288   } else {
00289     alarm->setEndOffset( KCal::Duration( offset ) );
00290   }
00291 
00292   // Repeating
00293   if ( mWidget->mRepeats->isChecked() ) {
00294     alarm->setRepeatCount( mWidget->mRepeatCount->value() );
00295     alarm->setSnoozeTime( mWidget->mRepeatInterval->value() );
00296   } else {
00297     alarm->setRepeatCount( 0 );
00298   }
00299 
00300   switch ( mWidget->mAlarmType->selectedId() ) {
00301     case 1: // Audio
00302         alarm->setAudioAlarm( mWidget->mSoundFile->url() );
00303         break;
00304     case 2: // Procedure
00305         alarm->setProcedureAlarm( mWidget->mApplication->url(), mWidget->mAppArguments->text() );
00306         break;
00307     case 3: { // Email
00308         QStringList addresses = KPIM::splitEmailAddrList( mWidget->mEmailAddress->text() );
00309         QValueList<KCal::Person> add;
00310         for ( QStringList::Iterator it = addresses.begin(); it != addresses.end();
00311               ++it ) {
00312           add << KCal::Person( *it );
00313         }
00314         // TODO: Add a subject line and possibilities for attachments
00315         alarm->setEmailAlarm( QString::null, mWidget->mEmailText->text(),
00316                               add );
00317         break; }
00318     case 0: // Display
00319     default:
00320         alarm->setDisplayAlarm( mWidget->mDisplayText->text() );
00321         break;
00322   }
00323 }
00324 
00325 void KOEditorAlarms::selectionChanged( QListViewItem *listviewitem )
00326 {
00327   AlarmListViewItem *item = dynamic_cast<AlarmListViewItem*>(listviewitem);
00328   mCurrentItem = item;
00329   mWidget->mTimeGroup->setEnabled( item );
00330   mWidget->mTypeGroup->setEnabled( item );
00331   if ( item ) {
00332     readAlarm( item->alarm() );
00333   }
00334 }
00335 
00336 void KOEditorAlarms::slotOk()
00337 {
00338   // copy the mAlarms list
00339   if ( mAlarms ) {
00340     mAlarms->clear();
00341     QListViewItemIterator it( mWidget->mAlarmList );
00342     while ( it.current() ) {
00343       AlarmListViewItem *item = dynamic_cast<AlarmListViewItem*>(*it);
00344       if ( item ) {
00345         mAlarms->append( new KCal::Alarm( *(item->alarm()) ) );
00346       }
00347       ++it;
00348     }
00349   }
00350   accept();
00351 }
00352 
00353 void KOEditorAlarms::slotAdd()
00354 {
00355   mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, 0 );
00356   mWidget->mAlarmList->setCurrentItem( mCurrentItem );
00357 //   selectionChanged( mCurrentItem );
00358 }
00359 
00360 void KOEditorAlarms::slotDuplicate()
00361 {
00362   if ( mCurrentItem ) {
00363     mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, mCurrentItem->alarm() );
00364     mWidget->mAlarmList->setCurrentItem( mCurrentItem );
00365 //     selectionChanged( mCurrentItem );
00366   }
00367 }
00368 
00369 void KOEditorAlarms::slotRemove()
00370 {
00371   if ( mCurrentItem ) {
00372     delete mCurrentItem;
00373     mCurrentItem = dynamic_cast<AlarmListViewItem*>( mWidget->mAlarmList->currentItem() );
00374     mWidget->mAlarmList->setSelected( mCurrentItem, true );
00375 
00376   }
00377 }
00378 
00379 void KOEditorAlarms::init()
00380 {
00381   mInitializing = true;
00382   KCal::Alarm::List::ConstIterator it;
00383   for ( it = mAlarms->begin(); it != mAlarms->end(); ++it ) {
00384     new AlarmListViewItem( mWidget->mAlarmList, *it );
00385   }
00386   mWidget->mAlarmList->setSelected( mWidget->mAlarmList->firstChild(), true );
00387   mInitializing = false;
00388 }
00389 
00390 #include "koeditoralarms.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys