37 #include "kogroupware.h"
38 #include "freebusymanager.h"
39 #include "calendarview.h"
40 #include "mailscheduler.h"
42 #include "koincidenceeditor.h"
43 #include <libemailfunctions/email.h>
44 #include <libkcal/attendee.h>
45 #include <libkcal/journal.h>
46 #include <libkcal/incidenceformatter.h>
48 #include <tdemessagebox.h>
49 #include <kstandarddirs.h>
50 #include <kdirwatch.h>
56 FreeBusyManager *KOGroupware::mFreeBusyManager = 0;
58 KOGroupware *KOGroupware::mInstance = 0;
64 mInstance =
new KOGroupware( view, calendar );
68 KOGroupware *KOGroupware::instance()
71 Q_ASSERT( mInstance );
77 : TQObject( 0,
"kmgroupware_instance" ), mView(
view ), mCalendar( cal ), mDoNotNotify( false )
80 KDirWatch* watcher = KDirWatch::self();
81 watcher->addDir( locateLocal(
"data",
"korganizer/income.accepted/" ) );
82 watcher->addDir( locateLocal(
"data",
"korganizer/income.tentative/" ) );
83 watcher->addDir( locateLocal(
"data",
"korganizer/income.counter/" ) );
84 watcher->addDir( locateLocal(
"data",
"korganizer/income.cancel/" ) );
85 watcher->addDir( locateLocal(
"data",
"korganizer/income.reply/" ) );
86 watcher->addDir( locateLocal(
"data",
"korganizer/income.delegated/" ) );
87 connect( watcher, TQ_SIGNAL( dirty(
const TQString& ) ),
88 this, TQ_SLOT( incomingDirChanged(
const TQString& ) ) );
90 TQTimer::singleShot( 0,
this, TQ_SLOT(initialCheckForChanges()) );
93 void KOGroupware::initialCheckForChanges()
95 incomingDirChanged( locateLocal(
"data",
"korganizer/income.accepted/" ) );
96 incomingDirChanged( locateLocal(
"data",
"korganizer/income.tentative/" ) );
97 incomingDirChanged( locateLocal(
"data",
"korganizer/income.counter/" ) );
98 incomingDirChanged( locateLocal(
"data",
"korganizer/income.cancel/" ) );
99 incomingDirChanged( locateLocal(
"data",
"korganizer/income.reply/" ) );
100 incomingDirChanged( locateLocal(
"data",
"korganizer/income.delegated/" ) );
103 void KOGroupware::slotViewNewIncidenceChanger( IncidenceChangerBase* changer )
106 connect( changer, TQ_SIGNAL( incidenceAdded(
Incidence* ) ),
107 mFreeBusyManager, TQ_SLOT( slotPerhapsUploadFB() ) );
108 connect( changer, TQ_SIGNAL( incidenceChanged(
Incidence*,
Incidence*, KOGlobals::WhatChanged ) ),
109 mFreeBusyManager, TQ_SLOT( slotPerhapsUploadFB() ) );
110 connect( changer, TQ_SIGNAL( incidenceDeleted(
Incidence * ) ),
111 mFreeBusyManager, TQ_SLOT( slotPerhapsUploadFB() ) );
114 FreeBusyManager *KOGroupware::freeBusyManager()
116 if ( !mFreeBusyManager ) {
117 mFreeBusyManager =
new FreeBusyManager(
this,
"freebusymanager" );
118 mFreeBusyManager->setCalendar( mCalendar );
119 connect( mCalendar, TQ_SIGNAL( calendarChanged() ),
120 mFreeBusyManager, TQ_SLOT( slotPerhapsUploadFB() ) );
121 connect( mView, TQ_SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
122 this, TQ_SLOT( slotViewNewIncidenceChanger( IncidenceChangerBase* ) ) );
123 slotViewNewIncidenceChanger( mView->incidenceChanger() );
126 return mFreeBusyManager;
129 void KOGroupware::incomingDirChanged(
const TQString& path )
131 const TQString incomingDirName = locateLocal(
"data",
"korganizer/" )
133 if ( !path.startsWith( incomingDirName ) ) {
134 kdDebug(5850) <<
"incomingDirChanged: Wrong dir " << path << endl;
137 TQString action = path.mid( incomingDirName.length() );
138 while ( action.length() > 0 && action[ action.length()-1 ] ==
'/' )
140 action.truncate( action.length()-1 );
144 const TQStringList files = dir.entryList( TQDir::Files );
145 if ( files.isEmpty() )
150 TQFile f( path +
"/" + files[0] );
151 if (!f.open(IO_ReadOnly)) {
152 kdError(5850) <<
"Can't open file '" << files[0] <<
"'" << endl;
156 t.setEncoding( TQTextStream::UnicodeUTF8 );
157 TQString receiver = KPIM::getFirstEmailAddress( t.readLine() );
158 TQString iCal = t.read();
162 ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar, iCal );
164 TQString errorMessage;
165 if (mFormat.exception())
166 errorMessage = i18n(
"Error message: %1" ).arg( mFormat.exception()->message() );
167 kdDebug(5850) <<
"MailScheduler::retrieveTransactions() Error parsing "
168 << errorMessage << endl;
169 KMessageBox::detailedError( mView,
170 i18n(
"Error while processing an invitation or update."),
184 KCal::MailScheduler scheduler( mCalendar );
185 if ( action.startsWith(
"accepted" ) || action.startsWith(
"tentative" )
186 || action.startsWith(
"delegated" ) || action.startsWith(
"counter" ) ) {
189 KCal::Attendee::List attendees = incidence->
attendees();
190 KCal::Attendee::List::ConstIterator it;
191 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
192 if( (*it)->email() == receiver ) {
193 if ( action.startsWith(
"accepted" ) )
194 (*it)->setStatus( KCal::Attendee::Accepted );
195 else if ( action.startsWith(
"tentative" ) )
196 (*it)->setStatus( KCal::Attendee::Tentative );
197 else if ( KOPrefs::instance()->outlookCompatCounterProposals() && action.startsWith(
"counter" ) )
198 (*it)->setStatus( KCal::Attendee::Tentative );
199 else if ( action.startsWith(
"delegated" ) )
200 (*it)->setStatus( KCal::Attendee::Delegated );
204 if ( KOPrefs::instance()->outlookCompatCounterProposals() || !action.startsWith(
"counter" ) )
205 scheduler.acceptTransaction( incidence, method, status, receiver );
206 }
else if ( action.startsWith(
"cancel" ) )
208 scheduler.acceptTransaction( incidence, KCal::Scheduler::Cancel, status, receiver );
209 else if ( action.startsWith(
"reply" ) ) {
210 if ( method != Scheduler::Counter ) {
211 scheduler.acceptTransaction( incidence, method, status );
214 scheduler.acceptCounterProposal( incidence );
216 sendICalMessage( mView, Scheduler::Request, incidence, KOGlobals::INCIDENCEEDITED,
false );
219 kdError(5850) <<
"Unknown incoming action " << action << endl;
221 if ( action.startsWith(
"counter" ) ) {
222 mView->editIncidence( incidence, TQDate(),
true );
224 tmp->selectInvitationCounterProposal(
true );
229 class KOInvitationFormatterHelper :
public InvitationFormatterHelper
232 virtual TQString generateLinkURL(
const TQString &
id ) {
return "kmail:groupware_request_" + id; }
241 bool KOGroupware::sendICalMessage( TQWidget* parent,
244 KOGlobals::HowChanged action,
245 bool attendeeStatusChanged,
246 int dontAskForGroupware )
252 bool isOrganizer = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
268 if ( dontAskForGroupware == 1 ) {
269 rc = KMessageBox::Yes;
271 else if ( dontAskForGroupware == 2 ) {
272 rc = KMessageBox::No;
280 || incidence->
attendees().first()->email() != incidence->organizer().email() ) {
284 case KOGlobals::INCIDENCEEDITED:
285 txt = i18n(
"You changed the invitation \"%1\".\n"
286 "Do you want to email the attendees an update message?" ).
289 case KOGlobals::INCIDENCEDELETED:
290 Q_ASSERT( incidence->type() ==
"Event" || incidence->type() ==
"Todo" );
291 if ( incidence->type() ==
"Event" ) {
292 txt = i18n(
"You removed the invitation \"%1\".\n"
293 "Do you want to email the attendees that the event is canceled?" ).
295 }
else if ( incidence->type() ==
"Todo" ) {
296 txt = i18n(
"You removed the invitation \"%1\".\n"
297 "Do you want to email the attendees that the todo is canceled?" ).
301 case KOGlobals::INCIDENCEADDED:
302 if ( incidence->type() ==
"Event" ) {
303 txt = i18n(
"The event \"%1\" includes other people.\n"
304 "Do you want to email the invitation to the attendees?" ).
306 }
else if ( incidence->type() ==
"Todo" ) {
307 txt = i18n(
"The todo \"%1\" includes other people.\n"
308 "Do you want to email the invitation to the attendees?" ).
311 txt = i18n(
"This incidence includes other people. "
312 "Should an email be sent to the attendees?" );
316 kdError() <<
"Unsupported HowChanged action" << int( action ) << endl;
320 rc = KMessageBox::questionYesNo(
321 parent, txt, i18n(
"Group Scheduling Email" ),
322 KGuiItem( i18n(
"Send Email" ) ), KGuiItem( i18n(
"Do Not Send" ) ) );
326 }
else if( incidence->type() ==
"Todo" ) {
327 if( method == Scheduler::Request )
329 method = Scheduler::Reply;
332 TQString txt = i18n(
"Do you want to send a status update to the "
333 "organizer of this task?");
334 rc = KMessageBox::questionYesNo( parent, txt, TQString(), i18n(
"Send Update"), i18n(
"Do Not Send") );
335 }
else if( incidence->type() ==
"Event" ) {
337 if ( attendeeStatusChanged && method == Scheduler::Request ) {
338 txt = i18n(
"Your status as an attendee of this event changed. "
339 "Do you want to send a status update to the event organizer?" );
340 method = Scheduler::Reply;
341 rc = KMessageBox::questionYesNo( parent, txt, TQString(), i18n(
"Send Update"), i18n(
"Do Not Send") );
343 if( action == KOGlobals::INCIDENCEDELETED ) {
344 const TQStringList myEmails = KOPrefs::instance()->allEmails();
345 bool askConfirmation =
false;
346 for ( TQStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
347 TQString email = *it;
349 if (me && (me->
status()==KCal::Attendee::Accepted || me->
status()==KCal::Attendee::Delegated)) {
350 askConfirmation =
true;
355 if ( !askConfirmation ) {
359 txt = i18n(
"You had previously accepted an invitation to this event. "
360 "Do you want to send an updated response to the organizer "
361 "declining the invitation?" );
362 rc = KMessageBox::questionYesNo(
363 parent, txt, i18n(
"Group Scheduling Email" ),
364 KGuiItem( i18n(
"Send Update" ) ), KGuiItem( i18n(
"Do Not Send" ) ) );
365 setDoNotNotify( rc == KMessageBox::No );
367 txt = i18n(
"You are not the organizer of this event. Editing it will "
368 "bring your calendar out of sync with the organizer's calendar. "
369 "Do you really want to edit it?" );
370 rc = KMessageBox::warningYesNo( parent, txt );
371 return ( rc == KMessageBox::Yes );
375 kdWarning(5850) <<
"Groupware messages for Journals are not implemented yet!" << endl;
380 if ( rc == KMessageBox::Yes ) {
383 if( incidence->
summary().isEmpty() )
384 incidence->
setSummary( i18n(
"<No summary given>") );
387 KCal::MailScheduler scheduler( mCalendar );
388 scheduler.performTransaction( incidence, method );
391 }
else if ( rc == KMessageBox::No ) {
400 if ( !oldEvent || !newEvent || *oldEvent == *newEvent || !KOPrefs::instance()->mUseGroupwareCommunication )
402 if ( KOPrefs::instance()->outlookCompatCounterProposals() ) {
406 tmp->
addComment( i18n(
"Proposed new meeting time: %1 - %2").
407 arg( IncidenceFormatter::dateToString( newEvent->
dtStart() ),
408 IncidenceFormatter::dateToString( newEvent->
dtEnd() ) ) );
409 KCal::MailScheduler scheduler( calendar );
410 scheduler.performTransaction( tmp, Scheduler::Reply );
413 KCal::MailScheduler scheduler( calendar );
414 scheduler.performTransaction( newEvent, Scheduler::Counter );
418 #include "kogroupware.moc"
This is the main calendar widget.
virtual TQDateTime dtEnd() const
const Attendee::List & attendees() const
Attendee * attendeeByMail(const TQString &) const
void addComment(const TQString &comment)
virtual TQDateTime dtStart() const
void setSummary(const TQString &summary)
TQString description() const
void setDescription(const TQString &description)
This is the base class for the calendar component editors.
bool view(TQWidget *parent, Attachment *attachment)