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