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