korganizer

alarmdialog.cpp

00001 /*
00002     This file is part of the KOrganizer alarm daemon.
00003 
00004     Copyright (c) 2000,2003 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (c) 2009-2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
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 <qhbox.h>
00027 #include <qvbox.h>
00028 #include <qlabel.h>
00029 #include <qfile.h>
00030 #include <qspinbox.h>
00031 #include <qlayout.h>
00032 #include <qpushbutton.h>
00033 #include <qcstring.h>
00034 #include <qdatastream.h>
00035 #include <qsplitter.h>
00036 
00037 #include <dcopclient.h>
00038 #include <dcopref.h>
00039 #include <kapplication.h>
00040 #include <kconfig.h>
00041 #include <kdcopservicestarter.h>
00042 #include <kiconloader.h>
00043 #include <klocale.h>
00044 #include <kprocess.h>
00045 #include <kaudioplayer.h>
00046 #include <kdebug.h>
00047 #include <kmessagebox.h>
00048 #include <knotifyclient.h>
00049 #include <kcombobox.h>
00050 #include <klistview.h>
00051 #include <kwin.h>
00052 #include <klockfile.h>
00053 
00054 #include <libkcal/event.h>
00055 #include <libkcal/incidenceformatter.h>
00056 
00057 #include "koeventviewer.h"
00058 
00059 #include "alarmdialog.h"
00060 #include "alarmdialog.moc"
00061 
00062 static int defSuspendVal = 5;
00063 static int defSuspendUnit = 0; // 0=>minutes, 1=>hours, 2=>days, 3=>weeks
00064 
00065 class AlarmListItem : public KListViewItem
00066 {
00067   public:
00068     AlarmListItem( const QString &uid, QListView *parent )
00069       : KListViewItem( parent ), mUid( uid ), mNotified( false )
00070     {
00071     }
00072 
00073     ~AlarmListItem()
00074     {
00075     }
00076 
00077     int compare( QListViewItem *item, int iCol, bool bAscending ) const;
00078 
00079     QString mDisplayText;
00080 
00081     QString mUid;
00082     QDateTime mRemindAt;
00083     QDateTime mHappening;
00084     bool mNotified;
00085 };
00086 
00087 int AlarmListItem::compare( QListViewItem *item, int iCol, bool bAscending ) const
00088 {
00089   if ( iCol == 1 ) {
00090     AlarmListItem *pItem = static_cast<AlarmListItem *>( item );
00091     return pItem->mHappening.secsTo( mHappening );
00092   } else {
00093     return KListViewItem::compare( item, iCol, bAscending );
00094   }
00095 }
00096 
00097 typedef QValueList<AlarmListItem*> ItemList;
00098 
00099 AlarmDialog::AlarmDialog( KCal::CalendarResources *calendar, QWidget *parent, const char *name )
00100   : KDialogBase( Plain,
00101                  WType_TopLevel | WStyle_Customize | WStyle_StaysOnTop | WStyle_DialogBorder,
00102                  parent, name, false, i18n("Reminder"),
00103                  Ok | User1 | User2 | User3, NoDefault,
00104                  false, i18n("Edit..."), i18n("Dismiss All"), i18n("Dismiss Reminder") ),
00105                  mCalendar( calendar ), mSuspendTimer(this)
00106 {
00107   // User1 => Edit...
00108   // User2 => Dismiss All
00109   // User3 => Dismiss Selected
00110   //    Ok => Suspend
00111 
00112   connect( calendar, SIGNAL(calendarChanged()),
00113            this, SLOT(slotCalendarChanged()) );
00114 
00115   KGlobal::iconLoader()->addAppDir( "kdepim" );
00116   setButtonOK( i18n( "Suspend" ) );
00117 
00118   QWidget *topBox = plainPage();
00119   QBoxLayout *topLayout = new QVBoxLayout( topBox );
00120   topLayout->setSpacing( spacingHint() );
00121 
00122   QLabel *label = new QLabel( i18n("The following items triggered reminders:"), topBox );
00123   topLayout->addWidget( label );
00124 
00125   mSplitter = new QSplitter( Qt::Vertical, topBox );
00126   mSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
00127   topLayout->addWidget( mSplitter );
00128 
00129   mIncidenceListView = new KListView( mSplitter );
00130   mIncidenceListView->addColumn( i18n( "Summary" ) );
00131   mIncidenceListView->addColumn( i18n( "Date, Time" ) );
00132   mIncidenceListView->setSorting( 0, true );
00133   mIncidenceListView->setSorting( 1, true );
00134   mIncidenceListView->setSortColumn( 1 );
00135   mIncidenceListView->setShowSortIndicator( true );
00136   mIncidenceListView->setAllColumnsShowFocus( true );
00137   mIncidenceListView->setSelectionMode( QListView::Extended );
00138   connect( mIncidenceListView, SIGNAL(selectionChanged()), SLOT(updateButtons()) );
00139   connect( mIncidenceListView, SIGNAL(doubleClicked(QListViewItem*)), SLOT(edit()) );
00140   connect( mIncidenceListView, SIGNAL(currentChanged(QListViewItem*)), SLOT(showDetails()) );
00141   connect( mIncidenceListView, SIGNAL(selectionChanged()), SLOT(showDetails()) );
00142 
00143   mDetailView = new KOEventViewer( mCalendar, mSplitter );
00144   mDetailView->setFocus(); // set focus here to start with to make it harder
00145                            // to hit return by mistake and dismiss a reminder.
00146 
00147   QHBox *suspendBox = new QHBox( topBox );
00148   suspendBox->setSpacing( spacingHint() );
00149   topLayout->addWidget( suspendBox );
00150 
00151   QLabel *l = new QLabel( i18n("Suspend &duration:"), suspendBox );
00152   mSuspendSpin = new QSpinBox( 1, 9999, 1, suspendBox );
00153   mSuspendSpin->setValue( defSuspendVal );  // default suspend duration
00154   l->setBuddy( mSuspendSpin );
00155 
00156   mSuspendUnit = new KComboBox( suspendBox );
00157   mSuspendUnit->insertItem( i18n("minute(s)") );
00158   mSuspendUnit->insertItem( i18n("hour(s)") );
00159   mSuspendUnit->insertItem( i18n("day(s)") );
00160   mSuspendUnit->insertItem( i18n("week(s)") );
00161   mSuspendUnit->setCurrentItem( defSuspendUnit );
00162 
00163   connect( &mSuspendTimer, SIGNAL(timeout()), SLOT(wakeUp()) );
00164 
00165   setMainWidget( mIncidenceListView );
00166   mIncidenceListView->setMinimumSize( 500, 50 );
00167 
00168   readLayout();
00169 }
00170 
00171 AlarmDialog::~AlarmDialog()
00172 {
00173   mIncidenceListView->clear();
00174 }
00175 
00176 AlarmListItem *AlarmDialog::searchByUid( const QString &uid )
00177 {
00178   AlarmListItem *found = 0;
00179   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
00180     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00181     if ( item->mUid == uid ) {
00182       found = item;
00183       break;
00184     }
00185     ++it;
00186   }
00187   return found;
00188 }
00189 
00190 static QString etc = i18n( "elipsis", "..." );
00191 static QString cleanSummary( const QString &summary )
00192 {
00193   uint maxLen = 45;
00194   QString retStr = summary;
00195   retStr.replace( '\n', ' ' );
00196   if ( retStr.length() > maxLen ) {
00197     maxLen -= etc.length();
00198     retStr = retStr.left( maxLen );
00199     retStr += etc;
00200   }
00201   return retStr;
00202 }
00203 
00204 void AlarmDialog::readLayout()
00205 {
00206   KConfig *config = kapp->config();
00207   config->setGroup( "Layout" );
00208   QValueList<int> sizes = config->readIntListEntry( "SplitterSizes" );
00209   if ( sizes.count() == 2 ) {
00210     mSplitter->setSizes( sizes );
00211   }
00212   mSplitter->setCollapsible( mIncidenceListView, false );
00213   mSplitter->setCollapsible( mDetailView, false );
00214 }
00215 
00216 void AlarmDialog::writeLayout()
00217 {
00218   KConfig *config = kapp->config();
00219   config->setGroup( "Layout" );
00220   QValueList<int> list = mSplitter->sizes();
00221   config->writeEntry( "SplitterSizes", list );
00222 }
00223 
00224 void AlarmDialog::addIncidence( Incidence *incidence,
00225                                 const QDateTime &reminderAt,
00226                                 const QString &displayText )
00227 {
00228   AlarmListItem *item = searchByUid( incidence->uid() );
00229   if ( !item ) {
00230     item = new AlarmListItem( incidence->uid(), mIncidenceListView );
00231   }
00232   item->mNotified = false;
00233   item->mHappening = QDateTime();
00234   item->mRemindAt = reminderAt;
00235   item->mDisplayText = displayText;
00236   item->setText( 0, cleanSummary( incidence->summary() ) );
00237   item->setText( 1, QString() );
00238 
00239   QString displayStr;
00240   const QDateTime dateTime = triggerDateForIncidence( incidence, reminderAt, displayStr );
00241 
00242   item->mHappening = dateTime;
00243   item->setText( 1, displayStr );
00244 
00245   if ( incidence->type() == "Event" ) {
00246     item->setPixmap( 0, SmallIcon( "appointment" ) );
00247   } else {
00248     item->setPixmap( 0, SmallIcon( "todo" ) );
00249   }
00250 
00251   if ( activeCount() == 1 ) { // previously empty
00252     mIncidenceListView->clearSelection();
00253     item->setSelected( true );
00254   }
00255   showDetails();
00256 }
00257 
00258 void AlarmDialog::slotOk()
00259 {
00260   suspend();
00261 }
00262 
00263 void AlarmDialog::slotUser1()
00264 {
00265   edit();
00266 }
00267 
00268 void AlarmDialog::slotUser2()
00269 {
00270   dismissAll();
00271 }
00272 
00273 void AlarmDialog::slotUser3()
00274 {
00275   dismissCurrent();
00276 }
00277 
00278 void AlarmDialog::dismissCurrent()
00279 {
00280   ItemList selection = selectedItems();
00281   for ( ItemList::Iterator it = selection.begin(); it != selection.end(); ++it ) {
00282     if ( (*it)->itemBelow() )
00283       (*it)->itemBelow()->setSelected( true );
00284     else if ( (*it)->itemAbove() )
00285       (*it)->itemAbove()->setSelected( true );
00286     delete *it;
00287   }
00288   if ( activeCount() == 0 ) {
00289     writeLayout();
00290     accept();
00291   } else {
00292     updateButtons();
00293     showDetails();
00294   }
00295   emit reminderCount( activeCount() );
00296 }
00297 
00298 void AlarmDialog::dismissAll()
00299 {
00300   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
00301     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00302     if ( !item->isVisible() ) {
00303       ++it;
00304       continue;
00305     }
00306     mIncidenceListView->takeItem( item );
00307     delete item;
00308   }
00309   setTimer();
00310   writeLayout();
00311   accept();
00312   emit reminderCount( activeCount() );
00313 }
00314 
00315 void AlarmDialog::edit()
00316 {
00317   ItemList selection = selectedItems();
00318   if ( selection.count() != 1 ) {
00319     return;
00320   }
00321   Incidence *incidence = mCalendar->incidence( selection.first()->mUid );
00322   if ( !incidence ) {
00323     return;
00324   }
00325   QDate dt = selection.first()->mRemindAt.date();
00326 
00327   if ( incidence->isReadOnly() ) {
00328     KMessageBox::sorry(
00329       this,
00330       i18n( "\"%1\" is a read-only item so modifications are not possible." ).
00331       arg( cleanSummary( incidence->summary() ) ) );
00332     return;
00333   }
00334 
00335   if ( !ensureKorganizerRunning() ) {
00336     KMessageBox::error(
00337       this,
00338       i18n( "Could not start KOrganizer so editing is not possible." ) );
00339     return;
00340   }
00341 
00342   QByteArray data;
00343   QDataStream arg( data, IO_WriteOnly );
00344   arg << incidence->uid();
00345   arg << dt;
00346   //kdDebug(5890) << "editing incidence " << incidence->summary() << endl;
00347   if ( !kapp->dcopClient()->send( "korganizer", "KOrganizerIface",
00348                                   "editIncidence(QString,QDate)",
00349                                   data ) ) {
00350     KMessageBox::error(
00351       this,
00352       i18n( "An internal KOrganizer error occurred attempting to start the incidence editor" ) );
00353     return;
00354   }
00355 
00356   // get desktop # where korganizer (or kontact) runs
00357   QByteArray replyData;
00358   QCString object, replyType;
00359   object = kapp->dcopClient()->isApplicationRegistered( "kontact" ) ?
00360            "kontact-mainwindow#1" : "KOrganizer MainWindow";
00361   if (!kapp->dcopClient()->call( "korganizer", object,
00362                             "getWinID()", 0, replyType, replyData, true, -1 ) ) {
00363   }
00364 
00365   if ( replyType == "int" ) {
00366     int desktop, window;
00367     QDataStream ds( replyData, IO_ReadOnly );
00368     ds >> window;
00369     desktop = KWin::windowInfo( window ).desktop();
00370 
00371     if ( KWin::currentDesktop() == desktop ) {
00372       KWin::iconifyWindow( winId(), false );
00373     } else {
00374       KWin::setCurrentDesktop( desktop );
00375     }
00376     KWin::activateWindow( KWin::transientFor( window ) );
00377   }
00378 }
00379 
00380 void AlarmDialog::suspend()
00381 {
00382   if ( !isVisible() )
00383     return;
00384 
00385   int unit=1;
00386   switch (mSuspendUnit->currentItem()) {
00387     case 3: // weeks
00388       unit *=  7;
00389     case 2: // days
00390       unit *= 24;
00391     case 1: // hours
00392       unit *= 60;
00393     case 0: // minutes
00394       unit *= 60;
00395     default:
00396       break;
00397   }
00398 
00399   AlarmListItem *selitem = 0;
00400   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00401     AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
00402     if ( item->isSelected() && item->isVisible() ) {
00403       item->setVisible( false );
00404       item->setSelected( false );
00405       item->mRemindAt = QDateTime::currentDateTime().addSecs( unit * mSuspendSpin->value() );
00406       item->mNotified = false;
00407       selitem = item;
00408     }
00409   }
00410   if ( selitem ) {
00411     if ( selitem->itemBelow() ) {
00412       selitem->itemBelow()->setSelected( true );
00413     } else if ( selitem->itemAbove() ) {
00414       selitem->itemAbove()->setSelected( true );
00415     }
00416   }
00417 
00418   // save suspended alarms too so they can be restored on restart
00419   // kolab/issue4108
00420   slotSave();
00421 
00422   setTimer();
00423   if ( activeCount() == 0 ) {
00424     writeLayout();
00425     accept();
00426   } else {
00427     updateButtons();
00428     showDetails();
00429   }
00430   emit reminderCount( activeCount() );
00431 }
00432 
00433 void AlarmDialog::setTimer()
00434 {
00435   int nextReminderAt = -1;
00436   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00437     AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
00438     if ( item->mRemindAt > QDateTime::currentDateTime() ) {
00439       int secs = QDateTime::currentDateTime().secsTo( item->mRemindAt );
00440       nextReminderAt = nextReminderAt <= 0 ? secs : QMIN( nextReminderAt, secs );
00441     }
00442   }
00443 
00444   if ( nextReminderAt >= 0 ) {
00445     mSuspendTimer.stop();
00446     mSuspendTimer.start( 1000 * (nextReminderAt + 1), true );
00447   }
00448 }
00449 
00450 void AlarmDialog::show()
00451 {
00452   mIncidenceListView->sort();
00453 
00454   // select the first item that hasn't already been notified
00455   mIncidenceListView->clearSelection();
00456   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00457     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00458     if ( !item->mNotified ) {
00459       (*it)->setSelected( true );
00460       break;
00461     }
00462   }
00463 
00464   updateButtons();
00465   showDetails();
00466 
00467   // reset the default suspend time
00468   mSuspendSpin->setValue( defSuspendVal );
00469   mSuspendUnit->setCurrentItem( defSuspendUnit );
00470 
00471   KDialogBase::show();
00472   KWin::deIconifyWindow( winId(), false );
00473   KWin::setState( winId(), NET::KeepAbove | NET::DemandsAttention );
00474   KWin::setOnAllDesktops( winId(), true );
00475   KWin::activateWindow( winId() );
00476   raise();
00477   setActiveWindow();
00478   if ( isMinimized() ) {
00479     showNormal();
00480   }
00481   eventNotification();
00482 }
00483 
00484 void AlarmDialog::eventNotification()
00485 {
00486   bool beeped = false, found = false;
00487 
00488   QValueList<AlarmListItem*> list;
00489   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00490     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00491     if ( !item->isVisible() || item->mNotified ) {
00492       continue;
00493     }
00494     Incidence *incidence = mCalendar->incidence( item->mUid );
00495     if ( !incidence ) {
00496       continue;
00497     }
00498     found = true;
00499     item->mNotified = true;
00500     Alarm::List alarms = incidence->alarms();
00501     Alarm::List::ConstIterator it;
00502     for ( it = alarms.begin(); it != alarms.end(); ++it ) {
00503       Alarm *alarm = *it;
00504       // FIXME: Check whether this should be done for all multiple alarms
00505       if (alarm->type() == Alarm::Procedure) {
00506         // FIXME: Add a message box asking whether the procedure should really be executed
00507         kdDebug(5890) << "Starting program: '" << alarm->programFile() << "'" << endl;
00508         KProcess proc;
00509         proc << QFile::encodeName(alarm->programFile());
00510         proc.start(KProcess::DontCare);
00511       }
00512       else if (alarm->type() == Alarm::Audio) {
00513         beeped = true;
00514         KAudioPlayer::play(QFile::encodeName(alarm->audioFile()));
00515       }
00516     }
00517   }
00518 
00519   if ( !beeped && found ) {
00520     KNotifyClient::beep();
00521   }
00522 }
00523 
00524 void AlarmDialog::wakeUp()
00525 {
00526   bool activeReminders = false;
00527   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00528     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00529     Incidence *incidence = mCalendar->incidence( item->mUid );
00530     if ( !incidence ) {
00531       delete item;
00532       continue;
00533     }
00534 
00535     if ( item->mRemindAt <= QDateTime::currentDateTime() ) {
00536       if ( !item->isVisible() ) {
00537         item->setVisible( true );
00538         item->setSelected( false );
00539       }
00540       activeReminders = true;
00541     } else {
00542       item->setVisible( false );
00543     }
00544   }
00545 
00546   if ( activeReminders )
00547     show();
00548   setTimer();
00549   showDetails();
00550   emit reminderCount( activeCount() );
00551 }
00552 
00553 void AlarmDialog::slotSave()
00554 {
00555   KConfig *config = kapp->config();
00556   KLockFile::Ptr lock = config->lockFile();
00557   if ( lock.data()->lock() != KLockFile::LockOK )
00558     return;
00559 
00560   config->setGroup( "General" );
00561   int numReminders = config->readNumEntry("Reminders", 0);
00562 
00563   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00564     AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
00565     Incidence *incidence = mCalendar->incidence( item->mUid );
00566     if ( !incidence ) {
00567       continue;
00568     }
00569     config->setGroup( QString("Incidence-%1").arg(numReminders + 1) );
00570     config->writeEntry( "UID", incidence->uid() );
00571     config->writeEntry( "RemindAt", item->mRemindAt );
00572     ++numReminders;
00573   }
00574 
00575   config->setGroup( "General" );
00576   config->writeEntry( "Reminders", numReminders );
00577   config->sync();
00578   lock.data()->unlock();
00579 }
00580 
00581 void AlarmDialog::closeEvent( QCloseEvent * )
00582 {
00583   slotSave();
00584   writeLayout();
00585   accept();
00586 }
00587 
00588 void AlarmDialog::updateButtons()
00589 {
00590   ItemList selection = selectedItems();
00591   enableButton( User1, selection.count() == 1 ); // can only edit 1 at a time
00592   enableButton( User3, selection.count() > 0 );  // dismiss 1 or more
00593   enableButton( Ok, selection.count() > 0 );     // suspend 1 or more
00594 }
00595 
00596 QValueList< AlarmListItem * > AlarmDialog::selectedItems() const
00597 {
00598   QValueList<AlarmListItem*> list;
00599   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00600     if ( it.current()->isSelected() )
00601       list.append( static_cast<AlarmListItem*>( it.current() ) );
00602   }
00603   return list;
00604 }
00605 
00606 int AlarmDialog::activeCount()
00607 {
00608   int count = 0;
00609   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00610     AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
00611     if ( item->isVisible() )
00612       ++count;
00613   }
00614   return count;
00615 }
00616 
00617 void AlarmDialog::suspendAll()
00618 {
00619   mIncidenceListView->clearSelection();
00620   for ( QListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
00621     if ( it.current()->isVisible() )
00622       it.current()->setSelected( true );
00623   }
00624   suspend();
00625 }
00626 
00627 void AlarmDialog::showDetails()
00628 {
00629   mDetailView->clearEvents( true );
00630   mDetailView->clear();
00631   AlarmListItem *item = static_cast<AlarmListItem*>( mIncidenceListView->selectedItems().first() );
00632   if ( !item || !item->isVisible() )
00633     return;
00634 
00635   Incidence *incidence = mCalendar->incidence( item->mUid );
00636   if ( !incidence ) {
00637     return;
00638   }
00639 
00640   if ( !item->mDisplayText.isEmpty() ) {
00641     QString txt = "<qt><p><b>" + item->mDisplayText + "</b></p></qt>";
00642     mDetailView->addText( txt );
00643   }
00644   item->setText( 0, cleanSummary( incidence->summary() ) );
00645   mDetailView->appendIncidence( incidence, item->mRemindAt.date() );
00646 }
00647 
00648 bool AlarmDialog::ensureKorganizerRunning() const
00649 {
00650   QString error;
00651   QCString dcopService;
00652 
00653   int result = KDCOPServiceStarter::self()->findServiceFor(
00654     "DCOP/Organizer", QString::null, QString::null, &error, &dcopService );
00655 
00656   if ( result == 0 ) {
00657     // OK, so korganizer (or kontact) is running. Now ensure the object we
00658     // want is available [that's not the case when kontact was already running,
00659     // but korganizer not loaded into it...]
00660     static const char* const dcopObjectId = "KOrganizerIface";
00661     QCString dummy;
00662     if ( !kapp->dcopClient()->findObject(
00663            dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) ) {
00664       DCOPRef ref( dcopService, dcopService ); // talk to KUniqueApplication or its kontact wrapper
00665       DCOPReply reply = ref.call( "load()" );
00666       if ( reply.isValid() && (bool)reply ) {
00667         Q_ASSERT( kapp->dcopClient()->findObject(
00668                     dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) );
00669       } else {
00670         kdWarning() << "Error loading " << dcopService << endl;
00671       }
00672     }
00673 
00674     // We don't do anything with it we just need it to be running
00675     return true;
00676 
00677   } else {
00678     kdWarning() << "Couldn't start DCOP/Organizer: " << dcopService
00679                 << " " << error << endl;
00680   }
00681   return false;
00682 }
00683 
00685 QDateTime AlarmDialog::triggerDateForIncidence( Incidence *incidence,
00686                                                 const QDateTime &reminderAt,
00687                                                 QString &displayStr )
00688 {
00689   // Will be simplified in trunk, with roles.
00690   QDateTime result;
00691 
00692   Alarm *alarm = incidence->alarms().first();
00693 
00694   if ( incidence->doesRecur() ) {
00695     result = incidence->recurrence()->getNextDateTime( reminderAt );
00696     displayStr = KGlobal::locale()->formatDateTime( result );
00697   }
00698 
00699   if ( incidence->type() == "Event" ) {
00700     if ( !result.isValid() ) {
00701       Event *event = static_cast<Event *>( incidence );
00702       result = alarm->hasStartOffset() ? event->dtStart() :
00703                                          event->dtEnd();
00704       displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
00705     }
00706   } else if ( incidence->type() == "Todo" ) {
00707     if ( !result.isValid() ) {
00708       Todo *todo = static_cast<Todo *>( incidence );
00709       result = alarm->hasStartOffset() && todo->dtStart().isValid() ? todo->dtStart():
00710                                                                       todo->dtDue();
00711      displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
00712     }
00713   }
00714 
00715   return result;
00716 }
00717 
00718 void AlarmDialog::slotCalendarChanged()
00719 {
00720   Incidence::List incidences = mCalendar->incidences();
00721   for ( Incidence::List::ConstIterator it = incidences.begin();
00722         it != incidences.constEnd(); ++it ) {
00723     Incidence *incidence = *it;
00724     AlarmListItem *item = searchByUid( incidence->uid() );
00725 
00726     if ( item ) {
00727       QString displayStr;
00728       const QDateTime dateTime = triggerDateForIncidence( incidence,
00729                                                           item->mRemindAt,
00730                                                           displayStr );
00731 
00732       const QString summary = cleanSummary( incidence->summary() );
00733 
00734       if ( displayStr != item->text( 1 ) || summary != item->text( 0 ) ) {
00735         item->setText( 1, displayStr );
00736         item->setText( 0, summary );
00737       }
00738     }
00739   }
00740 }
00741 
KDE Home | KDE Accessibility Home | Description of Access Keys