summaryrefslogtreecommitdiffstats
path: root/korganizer/korgac
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-01 00:37:02 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-01 00:37:02 +0000
commitcc29364f06178f8f6b457384f2ec37a042bd9d43 (patch)
tree7c77a3184c698bbf9d98cef09fb1ba8124daceba /korganizer/korgac
parent4f6c584bacc8c3c694228f36ada3de77a76614a6 (diff)
downloadtdepim-cc29364f06178f8f6b457384f2ec37a042bd9d43.tar.gz
tdepim-cc29364f06178f8f6b457384f2ec37a042bd9d43.zip
* Massive set of changes to bring in all fixes and enhancements from the Enterprise PIM branch
* Ensured that the Trinity changes were applied on top of those enhancements, and any redundancy removed * Added journal read support to the CalDAV resource * Fixed CalDAV resource to use events URL for tasks and journals when separate URL checkbox unchecked git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1170461 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'korganizer/korgac')
-rw-r--r--korganizer/korgac/alarmdialog.cpp534
-rw-r--r--korganizer/korgac/alarmdialog.h49
-rw-r--r--korganizer/korgac/koalarmclient.cpp22
-rw-r--r--korganizer/korgac/koalarmclient.h3
-rw-r--r--korganizer/korgac/korgac.desktop2
-rw-r--r--korganizer/korgac/testalarmdlg.cpp61
6 files changed, 522 insertions, 149 deletions
diff --git a/korganizer/korgac/alarmdialog.cpp b/korganizer/korgac/alarmdialog.cpp
index 6c9d62e90..839d463a9 100644
--- a/korganizer/korgac/alarmdialog.cpp
+++ b/korganizer/korgac/alarmdialog.cpp
@@ -2,6 +2,7 @@
This file is part of the KOrganizer alarm daemon.
Copyright (c) 2000,2003 Cornelius Schumacher <[email protected]>
+ Copyright (c) 2009-2010 Klar�lvdalens Datakonsult AB, a KDAB Group company <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,11 +32,14 @@
#include <tqpushbutton.h>
#include <tqcstring.h>
#include <tqdatastream.h>
+#include <tqsplitter.h>
+#include <dcopclient.h>
+#include <dcopref.h>
#include <kapplication.h>
#include <kconfig.h>
+#include <kdcopservicestarter.h>
#include <kiconloader.h>
-#include <dcopclient.h>
#include <klocale.h>
#include <kprocess.h>
#include <kaudioplayer.h>
@@ -48,64 +52,97 @@
#include <klockfile.h>
#include <libkcal/event.h>
+#include <libkcal/incidenceformatter.h>
#include "koeventviewer.h"
#include "alarmdialog.h"
#include "alarmdialog.moc"
+static int defSuspendVal = 5;
+static int defSuspendUnit = 0; // 0=>minutes, 1=>hours, 2=>days, 3=>weeks
+
class AlarmListItem : public KListViewItem
{
public:
- AlarmListItem( Incidence *incidence, TQListView *parent ) :
- KListViewItem( parent ),
- mIncidence( incidence->clone() ),
- mNotified( false )
- {}
+ AlarmListItem( const TQString &uid, TQListView *parent )
+ : KListViewItem( parent ), mUid( uid ), mNotified( false )
+ {
+ }
~AlarmListItem()
{
- delete mIncidence;
}
- Incidence *mIncidence;
+ int compare( TQListViewItem *item, int iCol, bool bAscending ) const;
+
+ TQString mDisplayText;
+
+ TQString mUid;
TQDateTime mRemindAt;
+ TQDateTime mHappening;
bool mNotified;
};
+int AlarmListItem::compare( TQListViewItem *item, int iCol, bool bAscending ) const
+{
+ if ( iCol == 1 ) {
+ AlarmListItem *pItem = static_cast<AlarmListItem *>( item );
+ return pItem->mHappening.secsTo( mHappening );
+ } else {
+ return KListViewItem::compare( item, iCol, bAscending );
+ }
+}
+
typedef TQValueList<AlarmListItem*> ItemList;
-AlarmDialog::AlarmDialog( TQWidget *parent, const char *name )
- : KDialogBase( Plain, WType_TopLevel | WStyle_Customize | WStyle_StaysOnTop |
- WStyle_DialogBorder,
- parent, name, false, i18n("Reminder"), Ok | User1 | User2 | User3, User1/*3*/,
- false, i18n("Dismiss all"), i18n("Edit..."), i18n("Suspend") ),
- mSuspendTimer(this)
+AlarmDialog::AlarmDialog( KCal::CalendarResources *calendar, TQWidget *parent, const char *name )
+ : KDialogBase( Plain,
+ WType_TopLevel | WStyle_Customize | WStyle_StaysOnTop | WStyle_DialogBorder,
+ parent, name, false, i18n("Reminder"),
+ Ok | User1 | User2 | User3, NoDefault,
+ false, i18n("Edit..."), i18n("Dismiss All"), i18n("Dismiss Reminder") ),
+ mCalendar( calendar ), mSuspendTimer(this)
{
+ // User1 => Edit...
+ // User2 => Dismiss All
+ // User3 => Dismiss Selected
+ // Ok => Suspend
+
+ connect( calendar, TQT_SIGNAL(calendarChanged()),
+ this, TQT_SLOT(slotCalendarChanged()) );
+
KGlobal::iconLoader()->addAppDir( "kdepim" );
- setButtonOK( i18n( "Dismiss" ) );
+ setButtonOK( i18n( "Suspend" ) );
TQWidget *topBox = plainPage();
TQBoxLayout *topLayout = new TQVBoxLayout( topBox );
topLayout->setSpacing( spacingHint() );
- TQLabel *label = new TQLabel( i18n("The following events triggered reminders:"),
- topBox );
+ TQLabel *label = new TQLabel( i18n("The following items triggered reminders:"), topBox );
topLayout->addWidget( label );
- mIncidenceListView = new KListView( topBox );
+ mSplitter = new TQSplitter( TQt::Vertical, topBox );
+ mSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
+ topLayout->addWidget( mSplitter );
+
+ mIncidenceListView = new KListView( mSplitter );
mIncidenceListView->addColumn( i18n( "Summary" ) );
- mIncidenceListView->addColumn( i18n( "Due" ) );
+ mIncidenceListView->addColumn( i18n( "Date, Time" ) );
+ mIncidenceListView->setSorting( 0, true );
+ mIncidenceListView->setSorting( 1, true );
+ mIncidenceListView->setSortColumn( 1 );
+ mIncidenceListView->setShowSortIndicator( true );
mIncidenceListView->setAllColumnsShowFocus( true );
mIncidenceListView->setSelectionMode( TQListView::Extended );
- topLayout->addWidget( mIncidenceListView );
connect( mIncidenceListView, TQT_SIGNAL(selectionChanged()), TQT_SLOT(updateButtons()) );
- connect( mIncidenceListView, TQT_SIGNAL(doubleClicked(TQListViewItem*)), TQT_SLOT(slotUser2()) );
+ connect( mIncidenceListView, TQT_SIGNAL(doubleClicked(TQListViewItem*)), TQT_SLOT(edit()) );
connect( mIncidenceListView, TQT_SIGNAL(currentChanged(TQListViewItem*)), TQT_SLOT(showDetails()) );
connect( mIncidenceListView, TQT_SIGNAL(selectionChanged()), TQT_SLOT(showDetails()) );
- mDetailView = new KOEventViewer( topBox );
- topLayout->addWidget( mDetailView );
+ mDetailView = new KOEventViewer( mCalendar, mSplitter );
+ mDetailView->setFocus(); // set focus here to start with to make it harder
+ // to hit return by mistake and dismiss a reminder.
TQHBox *suspendBox = new TQHBox( topBox );
suspendBox->setSpacing( spacingHint() );
@@ -113,7 +150,7 @@ AlarmDialog::AlarmDialog( TQWidget *parent, const char *name )
TQLabel *l = new TQLabel( i18n("Suspend &duration:"), suspendBox );
mSuspendSpin = new TQSpinBox( 1, 9999, 1, suspendBox );
- mSuspendSpin->setValue( 5 ); // default suspend duration
+ mSuspendSpin->setValue( defSuspendVal ); // default suspend duration
l->setBuddy( mSuspendSpin );
mSuspendUnit = new KComboBox( suspendBox );
@@ -121,11 +158,14 @@ AlarmDialog::AlarmDialog( TQWidget *parent, const char *name )
mSuspendUnit->insertItem( i18n("hour(s)") );
mSuspendUnit->insertItem( i18n("day(s)") );
mSuspendUnit->insertItem( i18n("week(s)") );
+ mSuspendUnit->setCurrentItem( defSuspendUnit );
+
connect( &mSuspendTimer, TQT_SIGNAL(timeout()), TQT_SLOT(wakeUp()) );
- // showButton( User2/*3*/, false );
+ setMainWidget( mIncidenceListView );
+ mIncidenceListView->setMinimumSize( 500, 50 );
- setMinimumSize( 300, 200 );
+ readLayout();
}
AlarmDialog::~AlarmDialog()
@@ -133,26 +173,82 @@ AlarmDialog::~AlarmDialog()
mIncidenceListView->clear();
}
-void AlarmDialog::addIncidence( Incidence *incidence, const TQDateTime &reminderAt )
+AlarmListItem *AlarmDialog::searchByUid( const TQString &uid )
+{
+ AlarmListItem *found = 0;
+ for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
+ AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
+ if ( item->mUid == uid ) {
+ found = item;
+ break;
+ }
+ ++it;
+ }
+ return found;
+}
+
+static TQString etc = i18n( "elipsis", "..." );
+static TQString cleanSummary( const TQString &summary )
{
- AlarmListItem *item = new AlarmListItem( incidence, mIncidenceListView );
- item->setText( 0, incidence->summary() );
+ uint maxLen = 45;
+ TQString retStr = summary;
+ retStr.replace( '\n', ' ' );
+ if ( retStr.length() > maxLen ) {
+ maxLen -= etc.length();
+ retStr = retStr.left( maxLen );
+ retStr += etc;
+ }
+ return retStr;
+}
+
+void AlarmDialog::readLayout()
+{
+ KConfig *config = kapp->config();
+ config->setGroup( "Layout" );
+ TQValueList<int> sizes = config->readIntListEntry( "SplitterSizes" );
+ if ( sizes.count() == 2 ) {
+ mSplitter->setSizes( sizes );
+ }
+ mSplitter->setCollapsible( mIncidenceListView, false );
+ mSplitter->setCollapsible( mDetailView, false );
+}
+
+void AlarmDialog::writeLayout()
+{
+ KConfig *config = kapp->config();
+ config->setGroup( "Layout" );
+ TQValueList<int> list = mSplitter->sizes();
+ config->writeEntry( "SplitterSizes", list );
+}
+
+void AlarmDialog::addIncidence( Incidence *incidence,
+ const TQDateTime &reminderAt,
+ const TQString &displayText )
+{
+ AlarmListItem *item = searchByUid( incidence->uid() );
+ if ( !item ) {
+ item = new AlarmListItem( incidence->uid(), mIncidenceListView );
+ }
+ item->mNotified = false;
+ item->mHappening = TQDateTime();
item->mRemindAt = reminderAt;
- Todo *todo;
- if ( dynamic_cast<Event*>( incidence ) ) {
+ item->mDisplayText = displayText;
+ item->setText( 0, cleanSummary( incidence->summary() ) );
+ item->setText( 1, TQString() );
+
+ TQString displayStr;
+ const TQDateTime dateTime = triggerDateForIncidence( incidence, reminderAt, displayStr );
+
+ item->mHappening = dateTime;
+ item->setText( 1, displayStr );
+
+ if ( incidence->type() == "Event" ) {
item->setPixmap( 0, SmallIcon( "appointment" ) );
- if ( incidence->doesRecur() ) {
- TQDateTime nextStart = incidence->recurrence()->getNextDateTime( reminderAt );
- if ( nextStart.isValid() )
- item->setText( 1, KGlobal::locale()->formatDateTime( nextStart ) );
- }
- if ( item->text( 1 ).isEmpty() )
- item->setText( 1, incidence->dtStartStr() );
- } else if ( (todo = dynamic_cast<Todo*>( incidence )) ) {
+ } else {
item->setPixmap( 0, SmallIcon( "todo" ) );
- item->setText( 1, todo->dtDueStr() );
}
- if ( activeCount() == 1 ) {// previously empty
+
+ if ( activeCount() == 1 ) { // previously empty
mIncidenceListView->clearSelection();
item->setSelected( true );
}
@@ -161,6 +257,26 @@ void AlarmDialog::addIncidence( Incidence *incidence, const TQDateTime &reminder
void AlarmDialog::slotOk()
{
+ suspend();
+}
+
+void AlarmDialog::slotUser1()
+{
+ edit();
+}
+
+void AlarmDialog::slotUser2()
+{
+ dismissAll();
+}
+
+void AlarmDialog::slotUser3()
+{
+ dismissCurrent();
+}
+
+void AlarmDialog::dismissCurrent()
+{
ItemList selection = selectedItems();
for ( ItemList::Iterator it = selection.begin(); it != selection.end(); ++it ) {
if ( (*it)->itemBelow() )
@@ -169,18 +285,96 @@ void AlarmDialog::slotOk()
(*it)->itemAbove()->setSelected( true );
delete *it;
}
- if ( activeCount() == 0 )
+ if ( activeCount() == 0 ) {
+ writeLayout();
accept();
- else {
+ } else {
updateButtons();
showDetails();
}
emit reminderCount( activeCount() );
}
-void AlarmDialog::slotUser1()
+void AlarmDialog::dismissAll()
{
- dismissAll();
+ for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
+ AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
+ if ( !item->isVisible() ) {
+ ++it;
+ continue;
+ }
+ mIncidenceListView->takeItem( item );
+ delete item;
+ }
+ setTimer();
+ writeLayout();
+ accept();
+ emit reminderCount( activeCount() );
+}
+
+void AlarmDialog::edit()
+{
+ ItemList selection = selectedItems();
+ if ( selection.count() != 1 ) {
+ return;
+ }
+ Incidence *incidence = mCalendar->incidence( selection.first()->mUid );
+ if ( !incidence ) {
+ return;
+ }
+ TQDate dt = selection.first()->mRemindAt.date();
+
+ if ( incidence->isReadOnly() ) {
+ KMessageBox::sorry(
+ this,
+ i18n( "\"%1\" is a read-only item so modifications are not possible." ).
+ arg( cleanSummary( incidence->summary() ) ) );
+ return;
+ }
+
+ if ( !ensureKorganizerRunning() ) {
+ KMessageBox::error(
+ this,
+ i18n( "Could not start KOrganizer so editing is not possible." ) );
+ return;
+ }
+
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << incidence->uid();
+ arg << dt;
+ //kdDebug(5890) << "editing incidence " << incidence->summary() << endl;
+ if ( !kapp->dcopClient()->send( "korganizer", "KOrganizerIface",
+ "editIncidence(TQString,TQDate)",
+ data ) ) {
+ KMessageBox::error(
+ this,
+ i18n( "An internal KOrganizer error occurred attempting to start the incidence editor" ) );
+ return;
+ }
+
+ // get desktop # where korganizer (or kontact) runs
+ TQByteArray replyData;
+ TQCString object, replyType;
+ object = kapp->dcopClient()->isApplicationRegistered( "kontact" ) ?
+ "kontact-mainwindow#1" : "KOrganizer MainWindow";
+ if (!kapp->dcopClient()->call( "korganizer", object,
+ "getWinID()", 0, replyType, replyData, true, -1 ) ) {
+ }
+
+ if ( replyType == "int" ) {
+ int desktop, window;
+ TQDataStream ds( replyData, IO_ReadOnly );
+ ds >> window;
+ desktop = KWin::windowInfo( window ).desktop();
+
+ if ( KWin::currentDesktop() == desktop ) {
+ KWin::iconifyWindow( winId(), false );
+ } else {
+ KWin::setCurrentDesktop( desktop );
+ }
+ KWin::activateWindow( KWin::transientFor( window ) );
+ }
}
void AlarmDialog::suspend()
@@ -202,6 +396,7 @@ void AlarmDialog::suspend()
break;
}
+ AlarmListItem *selitem = 0;
for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
if ( item->isSelected() && item->isVisible() ) {
@@ -209,13 +404,26 @@ void AlarmDialog::suspend()
item->setSelected( false );
item->mRemindAt = TQDateTime::currentDateTime().addSecs( unit * mSuspendSpin->value() );
item->mNotified = false;
+ selitem = item;
}
}
+ if ( selitem ) {
+ if ( selitem->itemBelow() ) {
+ selitem->itemBelow()->setSelected( true );
+ } else if ( selitem->itemAbove() ) {
+ selitem->itemAbove()->setSelected( true );
+ }
+ }
+
+ // save suspended alarms too so they can be restored on restart
+ // kolab/issue4108
+ slotSave();
setTimer();
- if ( activeCount() == 0 )
+ if ( activeCount() == 0 ) {
+ writeLayout();
accept();
- else {
+ } else {
updateButtons();
showDetails();
}
@@ -239,76 +447,37 @@ void AlarmDialog::setTimer()
}
}
-void AlarmDialog::slotUser2()
-{
- ItemList selection = selectedItems();
- if ( selection.count() != 1 )
- return;
- Incidence *incidence = selection.first()->mIncidence;
-
- if ( !kapp->dcopClient()->isApplicationRegistered( "korganizer" ) ) {
- if ( kapp->startServiceByDesktopName( "korganizer", TQString::null ) )
- KMessageBox::error( 0, i18n("Could not start KOrganizer.") );
- }
-
- kapp->dcopClient()->send( "korganizer", "KOrganizerIface",
- "editIncidence(TQString)",
- incidence->uid() );
-
- // get desktop # where korganizer (or kontact) runs
- TQByteArray replyData;
- TQCString object, replyType;
- object = kapp->dcopClient()->isApplicationRegistered( "kontact" ) ?
- "kontact-mainwindow#1" : "KOrganizer MainWindow";
- if (!kapp->dcopClient()->call( "korganizer", object,
- "getWinID()", 0, replyType, replyData, true, -1 ) ) {
- }
-
- if ( replyType == "int" ) {
- int desktop, window;
- TQDataStream ds( replyData, IO_ReadOnly );
- ds >> window;
- desktop = KWin::windowInfo( window ).desktop();
-
- if ( KWin::currentDesktop() == desktop ) {
- KWin::iconifyWindow( winId(), false );
- }
- else
- KWin::setCurrentDesktop( desktop );
-
- KWin::activateWindow( KWin::transientFor( window ) );
- }
-}
-
-void AlarmDialog::slotUser3()
+void AlarmDialog::show()
{
- suspend();
-}
+ mIncidenceListView->sort();
-void AlarmDialog::dismissAll()
-{
- for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ) {
+ // select the first item that hasn't already been notified
+ mIncidenceListView->clearSelection();
+ for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
- if ( !item->isVisible() ) {
- ++it;
- continue;
+ if ( !item->mNotified ) {
+ (*it)->setSelected( true );
+ break;
}
- delete item;
}
- setTimer();
- accept();
- emit reminderCount( activeCount() );
-}
-void AlarmDialog::show()
-{
- mIncidenceListView->clearSelection();
- if ( mIncidenceListView->firstChild() )
- mIncidenceListView->firstChild()->setSelected( true );
updateButtons();
+ showDetails();
+
+ // reset the default suspend time
+ mSuspendSpin->setValue( defSuspendVal );
+ mSuspendUnit->setCurrentItem( defSuspendUnit );
+
KDialogBase::show();
- KWin::setState( winId(), NET::KeepAbove );
+ KWin::deIconifyWindow( winId(), false );
+ KWin::setState( winId(), NET::KeepAbove | NET::DemandsAttention );
KWin::setOnAllDesktops( winId(), true );
+ KWin::activateWindow( winId() );
+ raise();
+ setActiveWindow();
+ if ( isMinimized() ) {
+ showNormal();
+ }
eventNotification();
}
@@ -319,11 +488,16 @@ void AlarmDialog::eventNotification()
TQValueList<AlarmListItem*> list;
for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
- if ( !item->isVisible() || item->mNotified )
+ if ( !item->isVisible() || item->mNotified ) {
+ continue;
+ }
+ Incidence *incidence = mCalendar->incidence( item->mUid );
+ if ( !incidence ) {
continue;
+ }
found = true;
item->mNotified = true;
- Alarm::List alarms = item->mIncidence->alarms();
+ Alarm::List alarms = incidence->alarms();
Alarm::List::ConstIterator it;
for ( it = alarms.begin(); it != alarms.end(); ++it ) {
Alarm *alarm = *it;
@@ -351,7 +525,13 @@ void AlarmDialog::wakeUp()
{
bool activeReminders = false;
for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
- AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
+ AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
+ Incidence *incidence = mCalendar->incidence( item->mUid );
+ if ( !incidence ) {
+ delete item;
+ continue;
+ }
+
if ( item->mRemindAt <= TQDateTime::currentDateTime() ) {
if ( !item->isVisible() ) {
item->setVisible( true );
@@ -381,9 +561,13 @@ void AlarmDialog::slotSave()
int numReminders = config->readNumEntry("Reminders", 0);
for ( TQListViewItemIterator it( mIncidenceListView ) ; it.current() ; ++it ) {
- AlarmListItem * item = static_cast<AlarmListItem*>( it.current() );
- config->setGroup( TQString("Incidence-%1").arg(numReminders) );
- config->writeEntry( "UID", item->mIncidence->uid() );
+ AlarmListItem *item = static_cast<AlarmListItem*>( it.current() );
+ Incidence *incidence = mCalendar->incidence( item->mUid );
+ if ( !incidence ) {
+ continue;
+ }
+ config->setGroup( TQString("Incidence-%1").arg(numReminders + 1) );
+ config->writeEntry( "UID", incidence->uid() );
config->writeEntry( "RemindAt", item->mRemindAt );
++numReminders;
}
@@ -394,12 +578,19 @@ void AlarmDialog::slotSave()
lock.data()->unlock();
}
+void AlarmDialog::closeEvent( TQCloseEvent * )
+{
+ slotSave();
+ writeLayout();
+ accept();
+}
+
void AlarmDialog::updateButtons()
{
ItemList selection = selectedItems();
- enableButton( User2, selection.count() == 1 );
- enableButton( Ok, selection.count() > 0 );
- enableButton( User3, selection.count() > 0 );
+ enableButton( User1, selection.count() == 1 ); // can only edit 1 at a time
+ enableButton( User3, selection.count() > 0 ); // dismiss 1 or more
+ enableButton( Ok, selection.count() > 0 ); // suspend 1 or more
}
TQValueList< AlarmListItem * > AlarmDialog::selectedItems() const
@@ -437,8 +628,113 @@ void AlarmDialog::showDetails()
{
mDetailView->clearEvents( true );
mDetailView->clear();
- AlarmListItem *item = static_cast<AlarmListItem*>( mIncidenceListView->currentItem() );
+ AlarmListItem *item = static_cast<AlarmListItem*>( mIncidenceListView->selectedItems().first() );
if ( !item || !item->isVisible() )
return;
- mDetailView->appendIncidence( item->mIncidence );
+
+ Incidence *incidence = mCalendar->incidence( item->mUid );
+ if ( !incidence ) {
+ return;
+ }
+
+ if ( !item->mDisplayText.isEmpty() ) {
+ TQString txt = "<qt><p><b>" + item->mDisplayText + "</b></p></qt>";
+ mDetailView->addText( txt );
+ }
+ item->setText( 0, cleanSummary( incidence->summary() ) );
+ mDetailView->appendIncidence( incidence, item->mRemindAt.date() );
+}
+
+bool AlarmDialog::ensureKorganizerRunning() const
+{
+ TQString error;
+ TQCString dcopService;
+
+ int result = KDCOPServiceStarter::self()->findServiceFor(
+ "DCOP/Organizer", TQString::null, TQString::null, &error, &dcopService );
+
+ if ( result == 0 ) {
+ // OK, so korganizer (or kontact) is running. Now ensure the object we
+ // want is available [that's not the case when kontact was already running,
+ // but korganizer not loaded into it...]
+ static const char* const dcopObjectId = "KOrganizerIface";
+ TQCString dummy;
+ if ( !kapp->dcopClient()->findObject(
+ dcopService, dcopObjectId, "", TQByteArray(), dummy, dummy ) ) {
+ DCOPRef ref( dcopService, dcopService ); // talk to KUniqueApplication or its kontact wrapper
+ DCOPReply reply = ref.call( "load()" );
+ if ( reply.isValid() && (bool)reply ) {
+ Q_ASSERT( kapp->dcopClient()->findObject(
+ dcopService, dcopObjectId, "", TQByteArray(), dummy, dummy ) );
+ } else {
+ kdWarning() << "Error loading " << dcopService << endl;
+ }
+ }
+
+ // We don't do anything with it we just need it to be running
+ return true;
+
+ } else {
+ kdWarning() << "Couldn't start DCOP/Organizer: " << dcopService
+ << " " << error << endl;
+ }
+ return false;
+}
+
+/** static */
+TQDateTime AlarmDialog::triggerDateForIncidence( Incidence *incidence,
+ const TQDateTime &reminderAt,
+ TQString &displayStr )
+{
+ // Will be simplified in trunk, with roles.
+ TQDateTime result;
+
+ Alarm *alarm = incidence->alarms().first();
+
+ if ( incidence->doesRecur() ) {
+ result = incidence->recurrence()->getNextDateTime( reminderAt );
+ displayStr = KGlobal::locale()->formatDateTime( result );
+ }
+
+ if ( incidence->type() == "Event" ) {
+ if ( !result.isValid() ) {
+ Event *event = static_cast<Event *>( incidence );
+ result = alarm->hasStartOffset() ? event->dtStart() :
+ event->dtEnd();
+ displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
+ }
+ } else if ( incidence->type() == "Todo" ) {
+ if ( !result.isValid() ) {
+ Todo *todo = static_cast<Todo *>( incidence );
+ result = alarm->hasStartOffset() && todo->dtStart().isValid() ? todo->dtStart():
+ todo->dtDue();
+ displayStr = IncidenceFormatter::dateTimeToString( result, false, true );
+ }
+ }
+
+ return result;
+}
+
+void AlarmDialog::slotCalendarChanged()
+{
+ Incidence::List incidences = mCalendar->incidences();
+ for ( Incidence::List::ConstIterator it = incidences.begin();
+ it != incidences.constEnd(); ++it ) {
+ Incidence *incidence = *it;
+ AlarmListItem *item = searchByUid( incidence->uid() );
+
+ if ( item ) {
+ TQString displayStr;
+ const TQDateTime dateTime = triggerDateForIncidence( incidence,
+ item->mRemindAt,
+ displayStr );
+
+ const TQString summary = cleanSummary( incidence->summary() );
+
+ if ( displayStr != item->text( 1 ) || summary != item->text( 0 ) ) {
+ item->setText( 1, displayStr );
+ item->setText( 0, summary );
+ }
+ }
+ }
}
diff --git a/korganizer/korgac/alarmdialog.h b/korganizer/korgac/alarmdialog.h
index 4c2162a54..75208f654 100644
--- a/korganizer/korgac/alarmdialog.h
+++ b/korganizer/korgac/alarmdialog.h
@@ -31,36 +31,48 @@
#include <kdialogbase.h>
#include <libkcal/event.h>
-#include <libkcal/calendarlocal.h>
+#include <libkcal/calendarresources.h>
using namespace KCal;
+class AlarmListItem;
class KOEventViewer;
-class TQSpinBox;
class KComboBox;
class KListView;
-class AlarmListItem;
+class TQSpinBox;
+class TQSplitter;
class AlarmDialog : public KDialogBase {
- Q_OBJECT
+ Q_OBJECT
public:
- AlarmDialog( TQWidget *parent = 0, const char *name = 0 );
- virtual ~AlarmDialog();
+ explicit AlarmDialog( CalendarResources *calendar, TQWidget *parent = 0, const char *name = 0 );
+
+ ~AlarmDialog();
- void addIncidence( Incidence *incidence, const TQDateTime &reminderAt );
+ void addIncidence( Incidence *incidence, const TQDateTime &reminderAt,
+ const TQString &displayText );
void eventNotification();
public slots:
- void slotOk();
- void slotUser1();
- void slotUser2();
- void slotUser3();
+
+ void slotOk(); // suspend
+ void slotUser1(); // edit
+ void slotUser2(); // dismiss all
+ void slotUser3(); // dismiss selected
void slotSave();
void wakeUp();
void show();
+ void edit();
void suspend();
void suspendAll();
void dismissAll();
+ void dismissCurrent();
+
+ /**
+ If an incidence changed, for example in korg, we must update
+ the date and summary shown in the list view.
+ */
+ void slotCalendarChanged();
signals:
void reminderCount( int count );
@@ -69,16 +81,29 @@ class AlarmDialog : public KDialogBase {
void updateButtons();
void showDetails();
+ protected:
+ void closeEvent( TQCloseEvent * );
+
private:
- bool startKOrganizer();
+
+ static TQDateTime triggerDateForIncidence( Incidence *inc,
+ const TQDateTime &reminderAt,
+ TQString &displayStr );
+
+ void readLayout();
+ void writeLayout();
+ AlarmListItem *searchByUid( const TQString &uid );
+ bool ensureKorganizerRunning() const;
void setTimer();
int activeCount();
TQValueList<AlarmListItem*> selectedItems() const;
+ CalendarResources *mCalendar;
KListView *mIncidenceListView;
KOEventViewer *mDetailView;
TQSpinBox *mSuspendSpin;
+ TQSplitter *mSplitter;
KComboBox *mSuspendUnit;
TQTimer mSuspendTimer;
};
diff --git a/korganizer/korgac/koalarmclient.cpp b/korganizer/korgac/koalarmclient.cpp
index a4298d7aa..ec19ce9aa 100644
--- a/korganizer/korgac/koalarmclient.cpp
+++ b/korganizer/korgac/koalarmclient.cpp
@@ -70,14 +70,17 @@ KOAlarmClient::KOAlarmClient( TQObject *parent, const char *name )
// load reminders that were active when quitting
config->setGroup( "General" );
int numReminders = config->readNumEntry( "Reminders", 0 );
- for ( int i=1; i<=numReminders; ++i )
- {
+ for ( int i = 1; i <= numReminders; ++i ) {
TQString group( TQString( "Incidence-%1" ).arg( i ) );
config->setGroup( group );
TQString uid = config->readEntry( "UID" );
TQDateTime dt = config->readDateTimeEntry( "RemindAt" );
- if ( !uid.isEmpty() )
- createReminder( mCalendar->incidence( uid ), dt );
+ if ( !uid.isEmpty() ) {
+ Incidence *i = mCalendar->incidence( uid );
+ if ( i && !i->alarms().isEmpty() ) {
+ createReminder( mCalendar, i, dt, TQString() );
+ }
+ }
config->deleteGroup( group );
}
config->setGroup( "General" );
@@ -115,24 +118,27 @@ void KOAlarmClient::checkAlarms()
for( it = alarms.begin(); it != alarms.end(); ++it ) {
kdDebug(5891) << "REMINDER: " << (*it)->parent()->summary() << endl;
Incidence *incidence = mCalendar->incidence( (*it)->parent()->uid() );
- createReminder( incidence, TQDateTime::currentDateTime() );
+ createReminder( mCalendar, incidence, from, (*it)->text() );
}
}
-void KOAlarmClient::createReminder( KCal::Incidence *incidence, TQDateTime dt )
+void KOAlarmClient::createReminder( KCal::CalendarResources *calendar,
+ KCal::Incidence *incidence,
+ const TQDateTime &dt,
+ const TQString &displayText )
{
if ( !incidence )
return;
if ( !mDialog ) {
- mDialog = new AlarmDialog();
+ mDialog = new AlarmDialog( calendar );
connect( mDialog, TQT_SIGNAL(reminderCount(int)), mDocker, TQT_SLOT(slotUpdate(int)) );
connect( mDocker, TQT_SIGNAL(suspendAllSignal()), mDialog, TQT_SLOT(suspendAll()) );
connect( mDocker, TQT_SIGNAL(dismissAllSignal()), mDialog, TQT_SLOT(dismissAll()) );
connect( this, TQT_SIGNAL( saveAllSignal() ), mDialog, TQT_SLOT( slotSave() ) );
}
- mDialog->addIncidence( incidence, dt );
+ mDialog->addIncidence( incidence, dt, displayText );
mDialog->wakeUp();
saveLastCheckTime();
}
diff --git a/korganizer/korgac/koalarmclient.h b/korganizer/korgac/koalarmclient.h
index 89c122c39..c8eee984e 100644
--- a/korganizer/korgac/koalarmclient.h
+++ b/korganizer/korgac/koalarmclient.h
@@ -69,7 +69,8 @@ class KOAlarmClient : public TQObject, virtual public AlarmClientIface, public K
void saveAllSignal();
private:
- void createReminder( KCal::Incidence *incidence, TQDateTime dt );
+ void createReminder( KCal::CalendarResources *calendar, KCal::Incidence *incidence,
+ const TQDateTime &dt, const TQString &displayText );
void saveLastCheckTime();
AlarmDockWindow *mDocker; // the panel icon
diff --git a/korganizer/korgac/korgac.desktop b/korganizer/korgac/korgac.desktop
index cad7d7e5e..6420a120f 100644
--- a/korganizer/korgac/korgac.desktop
+++ b/korganizer/korgac/korgac.desktop
@@ -22,7 +22,6 @@ Name[hu]=KOrganizer-emlékeztető kliens
Name[is]=Áminningarforrit fyrir KOrganizer
Name[it]=Client degli avvisi di KOrganizer
Name[ja]=KOrganizer リマインダクライアント
-Name[ka]=KOrganizer შემხსენებელის კლიენტი
Name[kk]=KOrganizer-дің еске салу клиенті
Name[km]=កម្មវិធី​រំលឹក​របស់ KOrganizer
Name[lt]=KOrganizer priminimų klientas
@@ -69,7 +68,6 @@ GenericName[hu]=KOrganizer emlékeztető szolgáltatás kliense
GenericName[is]=Áminningarpúki fyrir KOrganizer
GenericName[it]=Client del demone degli avvisi di KOrganizer
GenericName[ja]=KOrganizer リマインダデーモンクライアント
-GenericName[ka]=KOrganizer შემხსენებელის დემონის კლიენტი
GenericName[kk]=Organizer-дің еске салу қызметінің клиенті
GenericName[km]=កម្មវិធី​ដេមិន​អ្នក​រំលឹក​របស់ KOrganizer
GenericName[lt]=KOrganizer priminimų tarnybos klientas
diff --git a/korganizer/korgac/testalarmdlg.cpp b/korganizer/korgac/testalarmdlg.cpp
index 84fa51ed6..5a3ba5a18 100644
--- a/korganizer/korgac/testalarmdlg.cpp
+++ b/korganizer/korgac/testalarmdlg.cpp
@@ -29,6 +29,8 @@
#include <kdebug.h>
#include <klocale.h>
#include <kcmdlineargs.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
#include "alarmdialog.h"
@@ -39,6 +41,11 @@ int main(int argc,char **argv)
KApplication app;
+ KConfig c( locate( "config", "korganizerrc" ) );
+ c.setGroup( "Time & Date" );
+ TQString tz = c.readEntry( "TimeZoneId" );
+ CalendarResources *mCalendar = new CalendarResources( tz );
+
Event *e1 = new Event;
e1->setSummary( "This is a summary." );
TQDateTime now = TQDateTime::currentDateTime();
@@ -46,24 +53,64 @@ int main(int argc,char **argv)
e1->setDtEnd( now.addDays( 1 ) );
Alarm *a = e1->newAlarm();
// a->setProcedureAlarm( "/usr/X11R6/bin/xeyes" );
- a->setAudioAlarm( "/opt/kde/share/apps/korganizer/sounds/spinout.wav" );
+ a->setAudioAlarm( "/data/kde/share/apps/korganizer/sounds/spinout.wav" );
+ mCalendar->addEvent( e1 );
Todo *t1 = new Todo;
t1->setSummary( "To-do A" );
t1->setDtDue( now );
t1->newAlarm();
+ mCalendar->addTodo( t1 );
Event *e2 = new Event;
e2->setSummary( "This is another summary." );
- e2->setDtStart( now );
- e2->setDtEnd( now.addDays( 1 ) );
+ e2->setDtStart( now.addDays( 1 ) );
+ e2->setDtEnd( now.addDays( 2 ) );
e2->newAlarm();
+ mCalendar->addEvent( e2 );
+
+ Event *e3 = new Event;
+ e3->setSummary( "Meet with Fred" );
+ e3->setDtStart( now.addDays( 2 ) );
+ e3->setDtEnd( now.addDays( 3 ) );
+ e3->newAlarm();
+ mCalendar->addEvent( e3 );
+
+ Todo *t2 = new Todo;
+ t2->setSummary( "Something big is due today" );
+ t2->setDtDue( now );
+ t2->newAlarm();
+ mCalendar->addTodo( t2 );
+
+ Todo *t3 = new Todo;
+ t3->setSummary( "Be lazy" );
+ t3->setDtDue( now );
+ t3->newAlarm();
+ mCalendar->addTodo( t3 );
+
+ Event *e4 = new Event;
+ e4->setSummary( "Watch TV" );
+ e4->setDtStart( now.addSecs( 120 ) );
+ e4->setDtEnd( now.addSecs( 180 ) );
+ e4->newAlarm();
+ mCalendar->addEvent( e4 );
- AlarmDialog dlg;
+ AlarmDialog dlg( mCalendar, 0 );
app.setMainWidget( &dlg );
- dlg.addIncidence( e1, TQDateTime::currentDateTime() );
- dlg.addIncidence( t1, TQDateTime::currentDateTime() );
- dlg.addIncidence( e2, TQDateTime::currentDateTime() );
+ dlg.addIncidence( e2, TQDateTime::currentDateTime().addSecs( 60 ),
+ TQString() );
+ dlg.addIncidence( t1, TQDateTime::currentDateTime().addSecs( 300 ),
+ TQString( "THIS IS DISPLAY TEXT" ) );
+ dlg.addIncidence( e4, TQDateTime::currentDateTime().addSecs( 120 ),
+ TQString( "Fred and Barney get cloned" ) );
+ dlg.addIncidence( e3, TQDateTime::currentDateTime().addSecs( 240 ),
+ TQString() );
+ dlg.addIncidence( e1, TQDateTime::currentDateTime().addSecs( 180 ),
+ TQString() );
+ dlg.addIncidence( t2, TQDateTime::currentDateTime().addSecs( 600 ),
+ TQString( "THIS IS DISPLAY TEXT" ) );
+ dlg.addIncidence( t3, TQDateTime::currentDateTime().addSecs( 360 ),
+ TQString() );
dlg.show();
dlg.eventNotification();