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 
00039 #include <kurlrequester.h>
00040 #include <klocale.h>
00041 #include <kdebug.h>
00042 
00043 #include <libkcal/alarm.h>
00044 #include <libkcal/incidence.h>
00045 
00046 #include <libemailfunctions/email.h>
00047 
00048 class AlarmListViewItem : public QListViewItem
00049 {
00050   public:
00051     AlarmListViewItem( QListView *parent, KCal::Alarm *alarm );
00052     virtual ~AlarmListViewItem();
00053     KCal::Alarm *alarm() const { return mAlarm; }
00054     void construct();
00055     enum AlarmViewColumns { ColAlarmType=0, ColAlarmOffset, ColAlarmRepeat };
00056   protected:
00057     KCal::Alarm *mAlarm;
00058 };
00059 
00060 AlarmListViewItem::AlarmListViewItem( QListView *parent, KCal::Alarm *alarm )
00061     : QListViewItem( parent )
00062 {
00063   if ( alarm ) {
00064     mAlarm = new KCal::Alarm( *alarm );
00065   } else {
00066     mAlarm = new KCal::Alarm( 0 );
00067   }
00068   construct();
00069 }
00070 
00071 AlarmListViewItem::~AlarmListViewItem()
00072 {
00073   delete mAlarm;
00074 }
00075 
00076 void AlarmListViewItem::construct()
00077 {
00078   if ( mAlarm ) {
00079     // Alarm type:
00080     QString type( i18n("Unknown") );
00081     switch ( mAlarm->type() ) {
00082       case KCal::Alarm::Display: type = i18n("Reminder Dialog");
00083         break;
00084       case KCal::Alarm::Procedure: type = i18n("Application/Script");
00085         break;
00086       case KCal::Alarm::Email: type = i18n("Email");
00087         break;
00088       case KCal::Alarm::Audio: type = i18n("Audio");
00089         break;
00090       default: break;
00091     }
00092     setText( ColAlarmType, type );
00093 
00094     // Alarm offset:
00095     QString offsetstr;
00096     int offset = 0;
00097     if ( mAlarm->hasStartOffset() ) {
00098       offset = mAlarm->startOffset().asSeconds();
00099       if ( offset < 0 ) {
00100         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the start");
00101         offset = -offset;
00102       } else {
00103         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the start");
00104       }
00105     } else if ( mAlarm->hasEndOffset() ) {
00106       offset = mAlarm->endOffset().asSeconds();
00107       if ( offset < 0 ) {
00108         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the end");
00109         offset = -offset;
00110       } else {
00111         offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the end");
00112       }
00113     }
00114 
00115     offset = offset / 60; // make minutes
00116     int useoffset = offset;
00117 
00118     if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days?
00119       useoffset = offset / (24*60);
00120       offsetstr = offsetstr.arg( i18n("1 day", "%n days", useoffset ) );
00121     } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours?
00122       useoffset = offset / 60;
00123       offsetstr = offsetstr.arg( i18n("1 hour", "%n hours", useoffset ) );
00124     } else {
00125       useoffset = offset;
00126       offsetstr = offsetstr.arg( i18n("1 minute", "%n minutes", useoffset ) );
00127     }
00128     setText( ColAlarmOffset, offsetstr );
00129 
00130     // Alarm repeat
00131     if ( mAlarm->repeatCount()>0 ) {
00132       setText( ColAlarmRepeat, i18n("Yes") );
00133     }
00134   }
00135 }
00136 
00137 
00138 KOEditorAlarms::KOEditorAlarms( KCal::Alarm::List *alarms, QWidget *parent,
00139                                 const char *name )
00140   : KDialogBase( parent, name, true, i18n("Edit Reminders"), Ok | Apply | Cancel ), mAlarms( alarms ),mCurrentItem(0L)
00141 {
00142   setMainWidget( mWidget = new KOEditorAlarms_base( this ) );
00143   mWidget->mAlarmList->setColumnWidthMode( 0, QListView::Maximum );
00144   mWidget->mAlarmList->setColumnWidthMode( 1, QListView::Maximum );
00145   connect( mWidget->mAlarmList, SIGNAL( selectionChanged( QListViewItem * ) ),
00146            SLOT( selectionChanged( QListViewItem * ) ) );
00147   connect( mWidget->mAddButton, SIGNAL( clicked() ), SLOT( slotAdd() ) );
00148   connect( mWidget->mRemoveButton, SIGNAL( clicked() ), SLOT( slotRemove() ) );
00149   connect( mWidget->mDuplicateButton, SIGNAL( clicked() ), SLOT( slotDuplicate() ) );
00150 
00151   connect( mWidget->mAlarmOffset, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00152   connect( mWidget->mOffsetUnit, SIGNAL( activated( int ) ), SLOT( changed() ) );
00153   connect( mWidget->mBeforeAfter, SIGNAL( activated( int ) ), SLOT( changed() ) );
00154   connect( mWidget->mRepeats, SIGNAL( toggled( bool ) ), SLOT( changed() ) );
00155   connect( mWidget->mRepeatCount, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00156   connect( mWidget->mRepeatInterval, SIGNAL( valueChanged( int ) ), SLOT( changed() ) );
00157   connect( mWidget->mAlarmType, SIGNAL(clicked(int)), SLOT( changed() ) );
00158   connect( mWidget->mDisplayText, SIGNAL( textChanged() ), SLOT( changed() ) );
00159   connect( mWidget->mSoundFile, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00160   connect( mWidget->mApplication, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00161   connect( mWidget->mAppArguments, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00162   connect( mWidget->mEmailAddress, SIGNAL( textChanged( const QString & ) ), SLOT( changed() ) );
00163   connect( mWidget->mEmailText, SIGNAL( textChanged() ), SLOT( changed() ) );
00164 
00165   init();
00166 }
00167 
00168 KOEditorAlarms::~KOEditorAlarms()
00169 {
00170 }
00171 
00172 void KOEditorAlarms::changed()
00173 {
00174   if ( !mInitializing && mCurrentItem ) {
00175     writeAlarm( mCurrentItem->alarm() );
00176     mCurrentItem->construct();
00177   }
00178 }
00179 
00180 void KOEditorAlarms::readAlarm( KCal::Alarm *alarm )
00181 {
00182   if ( !alarm ) return;
00183 
00184   mInitializing = true;
00185 
00186   // Offsets
00187   int offset;
00188   int beforeafterpos = 0;
00189   if ( alarm->hasEndOffset() ) {
00190     beforeafterpos = 2;
00191     offset = alarm->endOffset().asSeconds();
00192   } else {
00193     // TODO: Also allow alarms at fixed times, not relative to start/end
00194     offset = alarm->startOffset().asSeconds();
00195   }
00196   // Negative offset means before the start/end...
00197   if ( offset < 0 ) {
00198     offset = -offset;
00199   } else {
00200     ++beforeafterpos;
00201   }
00202   mWidget->mBeforeAfter->setCurrentItem( beforeafterpos );
00203 
00204   offset = offset / 60; // make minutes
00205   int useoffset = offset;
00206 
00207   if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days?
00208     useoffset = offset / (24*60);
00209     mWidget->mOffsetUnit->setCurrentItem( 2 );
00210   } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours?
00211     useoffset = offset / 60;
00212     mWidget->mOffsetUnit->setCurrentItem( 1 );
00213   } else {
00214     useoffset = offset;
00215     mWidget->mOffsetUnit->setCurrentItem( 0 );
00216   }
00217   mWidget->mAlarmOffset->setValue( useoffset );
00218 
00219 
00220   // Repeating
00221   mWidget->mRepeats->setChecked( alarm->repeatCount()>0 );
00222   if ( alarm->repeatCount()>0 ) {
00223     mWidget->mRepeatCount->setValue( alarm->repeatCount() );
00224     mWidget->mRepeatInterval->setValue( alarm->snoozeTime() );
00225   }
00226 
00227   switch ( alarm->type() ) {
00228     case KCal::Alarm::Audio:
00229         mWidget->mAlarmType->setButton( 1 );
00230         mWidget->mSoundFile->setURL( alarm->audioFile() );
00231         break;
00232     case KCal::Alarm::Procedure:
00233         mWidget->mAlarmType->setButton( 2 );
00234         mWidget->mApplication->setURL( alarm->programFile() );
00235         mWidget->mAppArguments->setText( alarm->programArguments() );
00236         break;
00237     case KCal::Alarm::Email: {
00238         mWidget->mAlarmType->setButton( 3 );
00239         QValueList<KCal::Person> addresses = alarm->mailAddresses();
00240         QStringList add;
00241         for ( QValueList<KCal::Person>::ConstIterator it = addresses.begin();
00242               it != addresses.end(); ++it ) {
00243           add << (*it).fullName();
00244         }
00245         mWidget->mEmailAddress->setText( add.join(", ") );
00246         mWidget->mEmailText->setText( alarm->mailText() );
00247         break;}
00248     case KCal::Alarm::Display:
00249     case KCal::Alarm::Invalid:
00250     default:
00251         mWidget->mAlarmType->setButton( 0 );
00252         mWidget->mDisplayText->setText( alarm->text() );
00253         break;
00254   }
00255 
00256   mWidget->mTypeStack->raiseWidget( mWidget->mAlarmType->selectedId() );
00257 
00258   mInitializing = false;
00259 }
00260 
00261 void KOEditorAlarms::writeAlarm( KCal::Alarm *alarm )
00262 {
00263   // Offsets
00264   int offset = mWidget->mAlarmOffset->value()*60; // minutes
00265   int offsetunit = mWidget->mOffsetUnit->currentItem();
00266   if ( offsetunit >= 1 ) offset *= 60; // hours
00267   if ( offsetunit >= 2 ) offset *= 24; // days
00268   if ( offsetunit >= 3 ) offset *= 7; // weeks
00269 
00270   int beforeafterpos = mWidget->mBeforeAfter->currentItem();
00271   if ( beforeafterpos % 2 == 0 ) { // before -> negative
00272     offset = -offset;
00273   }
00274 
00275   // TODO: Add possibility to specify a given time for the reminder
00276   if ( beforeafterpos / 2 == 0 ) { // start offset
00277     alarm->setStartOffset( KCal::Duration( offset ) );
00278   } else {
00279     alarm->setEndOffset( KCal::Duration( offset ) );
00280   }
00281 
00282   // Repeating
00283   if ( mWidget->mRepeats->isChecked() ) {
00284     alarm->setRepeatCount( mWidget->mRepeatCount->value() );
00285     alarm->setSnoozeTime( mWidget->mRepeatInterval->value() );
00286   } else {
00287     alarm->setRepeatCount( 0 );
00288   }
00289 
00290   switch ( mWidget->mAlarmType->selectedId() ) {
00291     case 1: // Audio
00292         alarm->setAudioAlarm( mWidget->mSoundFile->url() );
00293         break;
00294     case 2: // Procedure
00295         alarm->setProcedureAlarm( mWidget->mApplication->url(), mWidget->mAppArguments->text() );
00296         break;
00297     case 3: { // Email
00298         QStringList addresses = KPIM::splitEmailAddrList( mWidget->mEmailAddress->text() );
00299         QValueList<KCal::Person> add;
00300         for ( QStringList::Iterator it = addresses.begin(); it != addresses.end();
00301               ++it ) {
00302           add << KCal::Person( *it );
00303         }
00304         // TODO: Add a subject line and possibilities for attachments
00305         alarm->setEmailAlarm( QString::null, mWidget->mEmailText->text(),
00306                               add );
00307         break; }
00308     case 0: // Display
00309     default:
00310         alarm->setDisplayAlarm( mWidget->mDisplayText->text() );
00311         break;
00312   }
00313 }
00314 
00315 void KOEditorAlarms::selectionChanged( QListViewItem *listviewitem )
00316 {
00317   AlarmListViewItem *item = dynamic_cast<AlarmListViewItem*>(listviewitem);
00318   mCurrentItem = item;
00319   mWidget->mTimeGroup->setEnabled( item );
00320   mWidget->mTypeGroup->setEnabled( item );
00321   if ( item ) {
00322     readAlarm( item->alarm() );
00323   }
00324 }
00325 
00326 void KOEditorAlarms::slotApply()
00327 {
00328   // copy the mAlarms list
00329   if ( mAlarms ) {
00330     mAlarms->clear();
00331     QListViewItemIterator it( mWidget->mAlarmList );
00332     while ( it.current() ) {
00333       AlarmListViewItem *item = dynamic_cast<AlarmListViewItem*>(*it);
00334       if ( item ) {
00335         mAlarms->append( new KCal::Alarm( *(item->alarm()) ) );
00336       }
00337       ++it;
00338     }
00339   }
00340 }
00341 
00342 void KOEditorAlarms::slotOk()
00343 {
00344   slotApply();
00345   accept();
00346 }
00347 
00348 void KOEditorAlarms::slotAdd()
00349 {
00350   mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, 0 );
00351   mWidget->mAlarmList->setCurrentItem( mCurrentItem );
00352 //   selectionChanged( mCurrentItem );
00353 }
00354 
00355 void KOEditorAlarms::slotDuplicate()
00356 {
00357   if ( mCurrentItem ) {
00358     mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, mCurrentItem->alarm() );
00359     mWidget->mAlarmList->setCurrentItem( mCurrentItem );
00360 //     selectionChanged( mCurrentItem );
00361   }
00362 }
00363 
00364 void KOEditorAlarms::slotRemove()
00365 {
00366   if ( mCurrentItem ) {
00367     delete mCurrentItem;
00368     mCurrentItem = dynamic_cast<AlarmListViewItem*>( mWidget->mAlarmList->currentItem() );
00369     mWidget->mAlarmList->setSelected( mCurrentItem, true );
00370 
00371   }
00372 }
00373 
00374 void KOEditorAlarms::init()
00375 {
00376   mInitializing = true;
00377   KCal::Alarm::List::ConstIterator it;
00378   for ( it = mAlarms->begin(); it != mAlarms->end(); ++it ) {
00379     new AlarmListViewItem( mWidget->mAlarmList, *it );
00380   }
00381   mWidget->mAlarmList->setSelected( mWidget->mAlarmList->firstChild(), true );
00382   mInitializing = false;
00383 }
00384 
00385 #include "koeditoralarms.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys