korganizer

alarmdialog.cpp
1/*
2 This file is part of the KOrganizer alarm daemon.
3
4 Copyright (c) 2000,2003 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2009-2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21 As a special exception, permission is given to link this program
22 with any edition of TQt, and distribute the resulting executable,
23 without including the source code for TQt in the source distribution.
24*/
25
26#include <tqhbox.h>
27#include <tqvbox.h>
28#include <tqlabel.h>
29#include <tqfile.h>
30#include <tqspinbox.h>
31#include <tqlayout.h>
32#include <tqpushbutton.h>
33#include <tqcstring.h>
34#include <tqdatastream.h>
35#include <tqsplitter.h>
36
37#include <dcopclient.h>
38#include <dcopref.h>
39#include <tdeapplication.h>
40#include <tdeconfig.h>
41#include <kdcopservicestarter.h>
42#include <kiconloader.h>
43#include <tdelocale.h>
44#include <tdeprocess.h>
45#include <kaudioplayer.h>
46#include <kdebug.h>
47#include <tdemessagebox.h>
48#include <knotifyclient.h>
49#include <kcombobox.h>
50#include <tdelistview.h>
51#include <twin.h>
52#include <klockfile.h>
53
54#include <libkcal/event.h>
55#include <libkcal/incidenceformatter.h>
56
57#include "koeventviewer.h"
58
59#include "alarmdialog.h"
60#include "alarmdialog.moc"
61
62static int defSuspendVal = 5;
63static int defSuspendUnit = 0; // 0=>minutes, 1=>hours, 2=>days, 3=>weeks
64
65class AlarmListItem : public TDEListViewItem
66{
67 public:
68 AlarmListItem( const TQString &uid, TQListView *parent )
69 : TDEListViewItem( parent ), mUid( uid ), mNotified( false )
70 {
71 }
72
73 ~AlarmListItem()
74 {
75 }
76
77 int compare( TQListViewItem *item, int iCol, bool bAscending ) const;
78
79 TQString mDisplayText;
80
81 TQString mUid;
82 TQDateTime mRemindAt;
83 TQDateTime mHappening;
84 bool mNotified;
85};
86
87int AlarmListItem::compare( TQListViewItem *item, int iCol, bool bAscending ) const
88{
89 if ( iCol == 1 ) {
90 AlarmListItem *pItem = static_cast<AlarmListItem *>( item );
91 return pItem->mHappening.secsTo( mHappening );
92 } else {
93 return TDEListViewItem::compare( item, iCol, bAscending );
94 }
95}
96
97typedef TQValueList<AlarmListItem*> ItemList;
98
99AlarmDialog::AlarmDialog( KCal::CalendarResources *calendar, TQWidget *parent, const char *name )
100 : KDialogBase( Plain,
101 WType_TopLevel | WStyle_Customize | WStyle_StaysOnTop | WStyle_DialogBorder,
102 parent, name, false, i18n("Reminder"),
103 Ok | User1 | User2 | User3, NoDefault,
104 false, i18n("Edit..."), i18n("Dismiss All"), i18n("Dismiss Reminder") ),
105 mCalendar( calendar ), mSuspendTimer(this)
106{
107 // User1 => Edit...
108 // User2 => Dismiss All
109 // User3 => Dismiss Selected
110 // Ok => Suspend
111
112 connect( calendar, TQ_SIGNAL(calendarChanged()),
113 this, TQ_SLOT(slotCalendarChanged()) );
114
115 TDEGlobal::iconLoader()->addAppDir( "tdepim" );
116 setButtonOK( i18n( "Suspend" ) );
117
118 TQWidget *topBox = plainPage();
119 TQBoxLayout *topLayout = new TQVBoxLayout( topBox );
120 topLayout->setSpacing( spacingHint() );
121
122 TQLabel *label = new TQLabel( i18n("The following items triggered reminders:"), topBox );
123 topLayout->addWidget( label );
124
125 mSplitter = new TQSplitter( TQt::Vertical, topBox );
126 mSplitter->setOpaqueResize( TDEGlobalSettings::opaqueResize() );
127 topLayout->addWidget( mSplitter );
128
129 mIncidenceListView = new TDEListView( mSplitter );
130 mIncidenceListView->addColumn( i18n( "Summary" ) );
131 mIncidenceListView->addColumn( i18n( "Date, Time" ) );
132 mIncidenceListView->setSorting( 0, true );
133 mIncidenceListView->setSorting( 1, true );
134 mIncidenceListView->setSortColumn( 1 );
135 mIncidenceListView->setShowSortIndicator( true );
136 mIncidenceListView->setAllColumnsShowFocus( true );
137 mIncidenceListView->setSelectionMode( TQListView::Extended );
138 connect( mIncidenceListView, TQ_SIGNAL(selectionChanged()), TQ_SLOT(updateButtons()) );
139 connect( mIncidenceListView, TQ_SIGNAL(doubleClicked(TQListViewItem*)), TQ_SLOT(edit()) );
140 connect( mIncidenceListView, TQ_SIGNAL(currentChanged(TQListViewItem*)), TQ_SLOT(showDetails()) );
141 connect( mIncidenceListView, TQ_SIGNAL(selectionChanged()), TQ_SLOT(showDetails()) );
142
143 mDetailView = new KOEventViewer( mCalendar, mSplitter );
144 mDetailView->setFocus(); // set focus here to start with to make it harder
145 // to hit return by mistake and dismiss a reminder.
146
147 TQHBox *suspendBox = new TQHBox( topBox );
148 suspendBox->setSpacing( spacingHint() );
149 topLayout->addWidget( suspendBox );
150
151 TQLabel *l = new TQLabel( i18n("Suspend &duration:"), suspendBox );
152 mSuspendSpin = new TQSpinBox( 1, 9999, 1, suspendBox );
153 mSuspendSpin->setValue( defSuspendVal ); // default suspend duration
154 l->setBuddy( mSuspendSpin );
155
156 mSuspendUnit = new KComboBox( suspendBox );
157 mSuspendUnit->insertItem( i18n("minute(s)") );
158 mSuspendUnit->insertItem( i18n("hour(s)") );
159 mSuspendUnit->insertItem( i18n("day(s)") );
160 mSuspendUnit->insertItem( i18n("week(s)") );
161 mSuspendUnit->setCurrentItem( defSuspendUnit );
162
163 connect( &mSuspendTimer, TQ_SIGNAL(timeout()), TQ_SLOT(wakeUp()) );
164
165 setMainWidget( mIncidenceListView );
166 mIncidenceListView->setMinimumSize( 500, 50 );
167
168 readLayout();
169}
170
171AlarmDialog::~AlarmDialog()
172{
173 mIncidenceListView->clear();
174}
175
176AlarmListItem *AlarmDialog::searchByUid( const TQString &uid )
177{
178 AlarmListItem *found = 0;
179 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
180 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
181 if ( item->mUid == uid ) {
182 found = item;
183 break;
184 }
185 ++it;
186 }
187 return found;
188}
189
190static TQString etc = i18n( "elipsis", "..." );
191static TQString cleanSummary( const TQString &summary )
192{
193 uint maxLen = 45;
194 TQString retStr = summary;
195 retStr.replace( '\n', ' ' );
196 if ( retStr.length() > maxLen ) {
197 maxLen -= etc.length();
198 retStr = retStr.left( maxLen );
199 retStr += etc;
200 }
201 return retStr;
202}
203
204void AlarmDialog::readLayout()
205{
206 TDEConfig *config = tdeApp->config();
207 config->setGroup( "Layout" );
208 TQValueList<int> sizes = config->readIntListEntry( "SplitterSizes" );
209 if ( sizes.count() == 2 ) {
210 mSplitter->setSizes( sizes );
211 }
212 mSplitter->setCollapsible( mIncidenceListView, false );
213 mSplitter->setCollapsible( mDetailView, false );
214}
215
216void AlarmDialog::writeLayout()
217{
218 TDEConfig *config = tdeApp->config();
219 config->setGroup( "Layout" );
220 TQValueList<int> list = mSplitter->sizes();
221 config->writeEntry( "SplitterSizes", list );
222}
223
224void AlarmDialog::addIncidence( Incidence *incidence,
225 const TQDateTime &reminderAt,
226 const TQString &displayText )
227{
228 AlarmListItem *item = searchByUid( incidence->uid() );
229 if ( !item ) {
230 item = new AlarmListItem( incidence->uid(), mIncidenceListView );
231 }
232 item->mNotified = false;
233 item->mHappening = TQDateTime();
234 item->mRemindAt = reminderAt;
235 item->mDisplayText = displayText;
236 item->setText( 0, cleanSummary( incidence->summary() ) );
237 item->setText( 1, TQString() );
238
239 TQString displayStr;
240 const TQDateTime dateTime = triggerDateForIncidence( incidence, reminderAt, displayStr );
241
242 item->mHappening = dateTime;
243 item->setText( 1, displayStr );
244
245 if ( incidence->type() == "Event" ) {
246 item->setPixmap( 0, SmallIcon( "appointment" ) );
247 } else {
248 item->setPixmap( 0, SmallIcon( "todo" ) );
249 }
250
251 if ( activeCount() == 1 ) { // previously empty
252 mIncidenceListView->clearSelection();
253 item->setSelected( true );
254 }
255 showDetails();
256}
257
258void AlarmDialog::slotOk()
259{
260 suspend();
261}
262
263void AlarmDialog::slotUser1()
264{
265 edit();
266}
267
268void AlarmDialog::slotUser2()
269{
270 dismissAll();
271}
272
273void AlarmDialog::slotUser3()
274{
275 dismissCurrent();
276}
277
278void AlarmDialog::dismissCurrent()
279{
280 ItemList selection = selectedItems();
281 for ( ItemList::Iterator it = selection.begin(); it != selection.end(); ++it ) {
282 if ( (*it)->itemBelow() )
283 (*it)->itemBelow()->setSelected( true );
284 else if ( (*it)->itemAbove() )
285 (*it)->itemAbove()->setSelected( true );
286 delete *it;
287 }
288 if ( activeCount() == 0 ) {
289 writeLayout();
290 accept();
291 } else {
292 updateButtons();
293 showDetails();
294 }
295 emit reminderCount( activeCount() );
296}
297
298void AlarmDialog::dismissAll()
299{
300 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
301 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
302 if ( !item->isVisible() ) {
303 ++it;
304 continue;
305 }
306 mIncidenceListView->takeItem( item );
307 delete item;
308 }
309 setTimer();
310 writeLayout();
311 accept();
312 emit reminderCount( activeCount() );
313}
314
315void AlarmDialog::edit()
316{
317 ItemList selection = selectedItems();
318 if ( selection.count() != 1 ) {
319 return;
320 }
321 Incidence *incidence = mCalendar->incidence( selection.first()->mUid );
322 if ( !incidence ) {
323 return;
324 }
325 TQDate dt = selection.first()->mRemindAt.date();
326
327 if ( incidence->isReadOnly() ) {
328 KMessageBox::sorry(
329 this,
330 i18n( "\"%1\" is a read-only item so modifications are not possible." ).
331 arg( cleanSummary( incidence->summary() ) ) );
332 return;
333 }
334
335 if ( !ensureKorganizerRunning() ) {
336 KMessageBox::error(
337 this,
338 i18n( "Could not start KOrganizer so editing is not possible." ) );
339 return;
340 }
341
342 TQByteArray data;
343 TQDataStream arg( data, IO_WriteOnly );
344 arg << incidence->uid();
345 arg << dt;
346 //kdDebug(5890) << "editing incidence " << incidence->summary() << endl;
347 if ( !tdeApp->dcopClient()->send( "korganizer", "KOrganizerIface",
348 "editIncidence(TQString,TQDate)",
349 data ) ) {
350 KMessageBox::error(
351 this,
352 i18n( "An internal KOrganizer error occurred attempting to start the incidence editor" ) );
353 return;
354 }
355
356 // get desktop # where korganizer (or kontact) runs
357 TQByteArray replyData;
358 TQCString object, replyType;
359 object = tdeApp->dcopClient()->isApplicationRegistered( "kontact" ) ?
360 "kontact-mainwindow#1" : "KOrganizer MainWindow";
361 if (!tdeApp->dcopClient()->call( "korganizer", object,
362 "getWinID()", 0, replyType, replyData, true, -1 ) ) {
363 }
364
365 if ( replyType == "int" ) {
366 int desktop, window;
367 TQDataStream ds( replyData, IO_ReadOnly );
368 ds >> window;
369 desktop = KWin::windowInfo( window ).desktop();
370
371 if ( KWin::currentDesktop() == desktop ) {
372 KWin::iconifyWindow( winId(), false );
373 } else {
374 KWin::setCurrentDesktop( desktop );
375 }
376 KWin::activateWindow( KWin::transientFor( window ) );
377 }
378}
379
380void AlarmDialog::suspend()
381{
382 if ( !isVisible() )
383 return;
384
385 int unit=1;
386 switch (mSuspendUnit->currentItem()) {
387 case 3: // weeks
388 unit *= 7;
389 case 2: // days
390 unit *= 24;
391 case 1: // hours
392 unit *= 60;
393 case 0: // minutes
394 unit *= 60;
395 default:
396 break;
397 }
398
399 AlarmListItem *selitem = 0;
400 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
401 AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
402 if ( item->isSelected() && item->isVisible() ) {
403 item->setVisible( false );
404 item->setSelected( false );
405 item->mRemindAt = TQDateTime::currentDateTime().addSecs( unit * mSuspendSpin->value() );
406 item->mNotified = false;
407 selitem = item;
408 }
409 }
410 if ( selitem ) {
411 if ( selitem->itemBelow() ) {
412 selitem->itemBelow()->setSelected( true );
413 } else if ( selitem->itemAbove() ) {
414 selitem->itemAbove()->setSelected( true );
415 }
416 }
417
418 // save suspended alarms too so they can be restored on restart
419 // kolab/issue4108
420 slotSave();
421
422 setTimer();
423 if ( activeCount() == 0 ) {
424 writeLayout();
425 accept();
426 } else {
427 updateButtons();
428 showDetails();
429 }
430 emit reminderCount( activeCount() );
431}
432
433void AlarmDialog::setTimer()
434{
435 int nextReminderAt = -1;
436 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
437 AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
438 if ( item->mRemindAt > TQDateTime::currentDateTime() ) {
439 int secs = TQDateTime::currentDateTime().secsTo( item->mRemindAt );
440 nextReminderAt = nextReminderAt <= 0 ? secs : TQMIN( nextReminderAt, secs );
441 }
442 }
443
444 if ( nextReminderAt >= 0 ) {
445 mSuspendTimer.stop();
446 mSuspendTimer.start( 1000 * (nextReminderAt + 1), true );
447 }
448}
449
450void AlarmDialog::show()
451{
452 mIncidenceListView->sort();
453
454 // select the first item that hasn't already been notified
455 mIncidenceListView->clearSelection();
456 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
457 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
458 if ( !item->mNotified ) {
459 (*it)->setSelected( true );
460 break;
461 }
462 }
463
464 updateButtons();
465 showDetails();
466
467 // reset the default suspend time
468 mSuspendSpin->setValue( defSuspendVal );
469 mSuspendUnit->setCurrentItem( defSuspendUnit );
470
471 KDialogBase::show();
472 KWin::deIconifyWindow( winId(), false );
473 KWin::setState( winId(), NET::KeepAbove | NET::DemandsAttention );
474 KWin::setOnAllDesktops( winId(), true );
475 KWin::activateWindow( winId() );
476 raise();
477 setActiveWindow();
478 if ( isMinimized() ) {
479 showNormal();
480 }
481 eventNotification();
482}
483
484void AlarmDialog::eventNotification()
485{
486 bool beeped = false, found = false;
487
488 TQValueList<AlarmListItem*> list;
489 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
490 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
491 if ( !item->isVisible() || item->mNotified ) {
492 continue;
493 }
494 Incidence *incidence = mCalendar->incidence( item->mUid );
495 if ( !incidence ) {
496 continue;
497 }
498 found = true;
499 item->mNotified = true;
500 Alarm::List alarms = incidence->alarms();
501 Alarm::List::ConstIterator c_it;
502 for ( c_it = alarms.begin(); c_it != alarms.end(); ++c_it ) {
503 Alarm *alarm = *c_it;
504 // FIXME: Check whether this should be done for all multiple alarms
505 if (alarm->type() == Alarm::Procedure) {
506 // FIXME: Add a message box asking whether the procedure should really be executed
507 kdDebug(5890) << "Starting program: '" << alarm->programFile() << "'" << endl;
508 TDEProcess proc;
509 proc << TQFile::encodeName(alarm->programFile()).data();
510 proc.start(TDEProcess::DontCare);
511 }
512 else if (alarm->type() == Alarm::Audio) {
513 beeped = true;
514 KAudioPlayer::play(TQFile::encodeName(alarm->audioFile()));
515 }
516 }
517 }
518
519 if ( !beeped && found ) {
520 KNotifyClient::beep();
521 }
522}
523
524void AlarmDialog::wakeUp()
525{
526 bool activeReminders = false;
527 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
528 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
529 Incidence *incidence = mCalendar->incidence( item->mUid );
530 if ( !incidence ) {
531 delete item;
532 continue;
533 }
534
535 if ( item->mRemindAt <= TQDateTime::currentDateTime() ) {
536 if ( !item->isVisible() ) {
537 item->setVisible( true );
538 item->setSelected( false );
539 }
540 activeReminders = true;
541 } else {
542 item->setVisible( false );
543 }
544 }
545
546 if ( activeReminders )
547 {
548 DCOPRef screensaver("kdesktop", "KScreensaverIface");
549 DCOPReply reply = screensaver.call("isBlanked");
550 bool res = true;
551 if (reply.isValid()) {
552 reply.get(res);
553 }
554 show();
555 if (res)
556 {
557 // Lower the dialog if the screensaver is active or its status unknown.
558 // This prevents reminders to show on a locked screen.
559 lower();
560 }
561 }
562 setTimer();
563 showDetails();
564 emit reminderCount( activeCount() );
565}
566
567void AlarmDialog::slotSave()
568{
569 TDEConfig *config = tdeApp->config();
570 TDELockFile::Ptr lock = config->lockFile();
571 if ( lock.data()->lock() != TDELockFile::LockOK )
572 return;
573
574 config->setGroup( "General" );
575 int numReminders = config->readNumEntry("Reminders", 0);
576
577 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
578 AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
579 Incidence *incidence = mCalendar->incidence( item->mUid );
580 if ( !incidence ) {
581 continue;
582 }
583 config->setGroup( TQString("Incidence-%1").arg(numReminders + 1) );
584 config->writeEntry( "UID", incidence->uid() );
585 config->writeEntry( "RemindAt", item->mRemindAt );
586 ++numReminders;
587 }
588
589 config->setGroup( "General" );
590 config->writeEntry( "Reminders", numReminders );
591 config->sync();
592 lock.data()->unlock();
593}
594
595void AlarmDialog::closeEvent( TQCloseEvent * )
596{
597 slotSave();
598 writeLayout();
599 accept();
600}
601
602void AlarmDialog::updateButtons()
603{
604 ItemList selection = selectedItems();
605 enableButton( User1, selection.count() == 1 ); // can only edit 1 at a time
606 enableButton( User3, selection.count() > 0 ); // dismiss 1 or more
607 enableButton( Ok, selection.count() > 0 ); // suspend 1 or more
608}
609
610TQValueList< AlarmListItem * > AlarmDialog::selectedItems() const
611{
612 TQValueList<AlarmListItem*> list;
613 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
614 if ( it.current()->isSelected() )
615 list.append( static_cast<AlarmListItem*>( it.current() ) );
616 }
617 return list;
618}
619
620int AlarmDialog::activeCount()
621{
622 int count = 0;
623 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
624 AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
625 if ( item->isVisible() )
626 ++count;
627 }
628 return count;
629}
630
631void AlarmDialog::suspendAll()
632{
633 mIncidenceListView->clearSelection();
634 for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
635 if ( it.current()->isVisible() )
636 it.current()->setSelected( true );
637 }
638 suspend();
639}
640
641void AlarmDialog::showDetails()
642{
643 mDetailView->clearEvents( true );
644 mDetailView->clear();
645 AlarmListItem *item = static_cast<AlarmListItem*>( mIncidenceListView->selectedItems().first() );
646 if ( !item || !item->isVisible() )
647 return;
648
649 Incidence *incidence = mCalendar->incidence( item->mUid );
650 if ( !incidence ) {
651 return;
652 }
653
654 if ( !item->mDisplayText.isEmpty() ) {
655 TQString txt = "<qt><p><b>" + item->mDisplayText + "</b></p></qt>";
656 mDetailView->addText( txt );
657 }
658 item->setText( 0, cleanSummary( incidence->summary() ) );
659 mDetailView->appendIncidence( incidence, item->mRemindAt.date() );
660}
661
662bool AlarmDialog::ensureKorganizerRunning() const
663{
664 TQString error;
665 TQCString dcopService;
666
667 int result = KDCOPServiceStarter::self()->findServiceFor(
668 "DCOP/Organizer", TQString(), TQString(), &error, &dcopService );
669
670 if ( result == 0 ) {
671 // OK, so korganizer (or kontact) is running. Now ensure the object we
672 // want is available [that's not the case when kontact was already running,
673 // but korganizer not loaded into it...]
674 static const char* const dcopObjectId = "KOrganizerIface";
675 TQCString dummy;
676 if ( !tdeApp->dcopClient()->findObject(
677 dcopService, dcopObjectId, "", TQByteArray(), dummy, dummy ) ) {
678 DCOPRef ref( dcopService, dcopService ); // talk to TDEUniqueApplication or its kontact wrapper
679 DCOPReply reply = ref.call( "load()" );
680 if ( reply.isValid() && (bool)reply ) {
681 Q_ASSERT( tdeApp->dcopClient()->findObject(
682 dcopService, dcopObjectId, "", TQByteArray(), dummy, dummy ) );
683 } else {
684 kdWarning() << "Error loading " << dcopService << endl;
685 }
686 }
687
688 // We don't do anything with it we just need it to be running
689 return true;
690
691 } else {
692 kdWarning() << "Couldn't start DCOP/Organizer: " << dcopService
693 << " " << error << endl;
694 }
695 return false;
696}
697
699TQDateTime AlarmDialog::triggerDateForIncidence( Incidence *incidence,
700 const TQDateTime &reminderAt,
701 TQString &displayStr )
702{
703 // Will be simplified in trunk, with roles.
704 TQDateTime result;
705
706 Alarm *alarm = incidence->alarms().first();
707
708 if ( incidence->doesRecur() ) {
709 result = incidence->recurrence()->getNextDateTime( reminderAt );
710 displayStr = TDEGlobal::locale()->formatDateTime( result );
711 }
712
713 if ( incidence->type() == "Event" ) {
714 if ( !result.isValid() ) {
715 Event *event = static_cast<Event *>( incidence );
716 result = alarm->hasStartOffset() ? event->dtStart() :
717 event->dtEnd();
718 displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
719 }
720 } else if ( incidence->type() == "Todo" ) {
721 if ( !result.isValid() ) {
722 Todo *todo = static_cast<Todo *>( incidence );
723 result = alarm->hasStartOffset() && todo->dtStart().isValid() ? todo->dtStart():
724 todo->dtDue();
725 displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
726 }
727 }
728
729 return result;
730}
731
732void AlarmDialog::slotCalendarChanged()
733{
734 Incidence::List incidences = mCalendar->incidences();
735 for ( Incidence::List::ConstIterator it = incidences.begin();
736 it != incidences.constEnd(); ++it ) {
737 Incidence *incidence = *it;
738 AlarmListItem *item = searchByUid( incidence->uid() );
739
740 if ( item ) {
741 TQString displayStr;
742 const TQDateTime dateTime = triggerDateForIncidence( incidence,
743 item->mRemindAt,
744 displayStr );
745
746 const TQString summary = cleanSummary( incidence->summary() );
747
748 if ( displayStr != item->text( 1 ) || summary != item->text( 0 ) ) {
749 item->setText( 1, displayStr );
750 item->setText( 0, summary );
751 }
752 }
753 }
754}
bool hasStartOffset() const
TQString audioFile() const
TQString programFile() const
Type type() const
TQString uid() const
bool isReadOnly() const
const Alarm::List & alarms() const
bool doesRecur() const
TQString summary() const
Recurrence * recurrence() const
TQDateTime getNextDateTime(const TQDateTime &preDateTime) const
TQDateTime dtStart(bool first=false) const
TQDateTime dtDue(bool first=false) const
Viewer widget for events.
Definition: koeventviewer.h:41