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