summaryrefslogtreecommitdiffabout
path: root/libkcal/scheduler.cpp
Unidiff
Diffstat (limited to 'libkcal/scheduler.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/scheduler.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/libkcal/scheduler.cpp b/libkcal/scheduler.cpp
new file mode 100644
index 0000000..253d8b7
--- a/dev/null
+++ b/libkcal/scheduler.cpp
@@ -0,0 +1,355 @@
1/*
2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qdir.h>
22#include <qfile.h>
23#include <qtextstream.h>
24
25#include <klocale.h>
26#include <kdebug.h>
27#include <kstandarddirs.h>
28
29#include "event.h"
30#include "todo.h"
31#include "freebusy.h"
32#include "icalformat.h"
33#include "calendar.h"
34
35#include "scheduler.h"
36
37using namespace KCal;
38
39ScheduleMessage::ScheduleMessage(IncidenceBase *incidence,int method,ScheduleMessage::Status status)
40{
41 mIncidence = incidence;
42 mMethod = method;
43 mStatus = status;
44}
45
46QString ScheduleMessage::statusName(ScheduleMessage::Status status)
47{
48 switch (status) {
49 case PublishNew:
50 return i18n("Publish");
51 case Obsolete:
52 return i18n("Obsolete");
53 case RequestNew:
54 return i18n("New Request");
55 case RequestUpdate:
56 return i18n("Updated Request");
57 default:
58 return i18n("Unknown Status: %1").arg(QString::number(status));
59 }
60}
61
62Scheduler::Scheduler(Calendar *calendar)
63{
64 mCalendar = calendar;
65 mFormat = new ICalFormat();
66}
67
68Scheduler::~Scheduler()
69{
70 delete mFormat;
71}
72
73bool Scheduler::acceptTransaction(IncidenceBase *incidence,Method method,ScheduleMessage::Status status)
74{
75 kdDebug() << "Scheduler::acceptTransaction " << endl;
76 switch (method) {
77 case Publish:
78 return acceptPublish(incidence, status, method);
79 case Request:
80 return acceptRequest(incidence, status);
81 case Add:
82 return acceptAdd(incidence, status);
83 case Cancel:
84 return acceptCancel(incidence, status);
85 case Declinecounter:
86 return acceptDeclineCounter(incidence, status);
87 case Reply:
88 return acceptReply(incidence, status, method);
89 case Refresh:
90 return acceptRefresh(incidence, status);
91 case Counter:
92 return acceptCounter(incidence, status);
93 default:
94 deleteTransaction(incidence);
95 return false;
96 }
97 deleteTransaction(incidence);
98 return false;
99}
100
101QString Scheduler::methodName(Method method)
102{
103 switch (method) {
104 case Publish:
105 return QString::fromLatin1("Publish");
106 case Request:
107 return QString::fromLatin1("Request");
108 case Refresh:
109 return QString::fromLatin1("Refresh");
110 case Cancel:
111 return QString::fromLatin1("Cancel");
112 case Add:
113 return QString::fromLatin1("Add");
114 case Reply:
115 return QString::fromLatin1("Reply");
116 case Counter:
117 return QString::fromLatin1("Counter");
118 case Declinecounter:
119 return QString::fromLatin1("Decline Counter");
120 default:
121 return QString::fromLatin1("Unknown");
122 }
123}
124
125QString Scheduler::translatedMethodName(Method method)
126{
127 switch (method) {
128 case Publish:
129 return i18n("Publish");
130 case Request:
131 return i18n("Request");
132 case Refresh:
133 return i18n("Refresh");
134 case Cancel:
135 return i18n("Cancel");
136 case Add:
137 return i18n("Add");
138 case Reply:
139 return i18n("Reply");
140 case Counter:
141 return i18n("counter proposal","Counter");
142 case Declinecounter:
143 return i18n("decline counter proposal","Decline Counter");
144 default:
145 return i18n("Unknown");
146 }
147}
148
149bool Scheduler::deleteTransaction(IncidenceBase *)
150{
151 return true;
152}
153
154bool Scheduler::acceptPublish(IncidenceBase *incidence,ScheduleMessage::Status status, Method method)
155{
156 if(incidence->type()=="FreeBusy") {
157 return acceptFreeBusy(incidence, method);
158 }
159 switch (status) {
160 case ScheduleMessage::Unknown:
161 case ScheduleMessage::PublishNew:
162 if (!mCalendar->event(incidence->uid())) {
163 Incidence *inc = static_cast<Incidence *>(incidence);
164 mCalendar->addIncidence(inc);
165 deleteTransaction(incidence);
166 }
167 return true;
168 case ScheduleMessage::Obsolete:
169 return true;
170 default:
171 deleteTransaction(incidence);
172 return false;
173 }
174 deleteTransaction(incidence);
175 return false;
176}
177
178bool Scheduler::acceptRequest(IncidenceBase *incidence,ScheduleMessage::Status status)
179{
180 Incidence *inc = static_cast<Incidence *>(incidence);
181 if (inc->type()=="FreeBusy") {
182 // reply to this request is handled in korganizer's incomingdialog
183 return true;
184 } else {
185 Event *even = mCalendar->event(incidence->uid());
186 if (even) {
187 if ( even->revision()<=inc->revision() ) {
188 if ( even->revision()==inc->revision() &&
189 even->lastModified()>inc->lastModified()) {
190 deleteTransaction(incidence);
191 return false;
192 }
193 mCalendar->deleteEvent(even);
194 } else {
195 deleteTransaction(incidence);
196 return false;
197 }
198 } else {
199 Todo *todo = mCalendar->todo(incidence->uid());
200 if (todo) {
201 if ( todo->revision()<=inc->revision() ) {
202 if ( todo->revision()==inc->revision() &&
203 todo->lastModified()>inc->lastModified()) {
204 deleteTransaction(incidence);
205 return false;
206 }
207 mCalendar->deleteTodo(todo);
208 } else {
209 deleteTransaction(incidence);
210 return false;
211 }
212 }
213 }
214 }
215 mCalendar->addIncidence(inc);
216 deleteTransaction(incidence);
217 return true;
218}
219
220bool Scheduler::acceptAdd(IncidenceBase *incidence,ScheduleMessage::Status status)
221{
222 deleteTransaction(incidence);
223 return false;
224}
225
226bool Scheduler::acceptCancel(IncidenceBase *incidence,ScheduleMessage::Status status)
227{
228 bool ret = false;
229 Event *even = mCalendar->event(incidence->uid());
230 if (even) {
231 mCalendar->deleteEvent(even);
232 ret = true;
233 } else {
234 Todo *todo = mCalendar->todo(incidence->uid());
235 if (todo) {
236 mCalendar->deleteTodo(todo);
237 ret = true;
238 }
239 }
240 deleteTransaction(incidence);
241 return ret;
242}
243
244bool Scheduler::acceptDeclineCounter(IncidenceBase *incidence,ScheduleMessage::Status status)
245{
246 deleteTransaction(incidence);
247 return false;
248}
249
250//bool Scheduler::acceptFreeBusy(Incidence *incidence,ScheduleMessage::Status status)
251//{
252// deleteTransaction(incidence);
253// return false;
254//}
255
256bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status status, Method method)
257{
258 if(incidence->type()=="FreeBusy") {
259 return acceptFreeBusy(incidence, method);
260 }
261 bool ret = false;
262 Event *ev = mCalendar->event(incidence->uid());
263 Todo *to = mCalendar->todo(incidence->uid());
264 if (ev || to) {
265 //get matching attendee in calendar
266 kdDebug(5800) << "Scheduler::acceptTransaction match found!" << endl;
267 QPtrList<Attendee> attendeesIn = incidence->attendees();
268 QPtrList<Attendee> attendeesEv;
269 if (ev) attendeesEv = ev->attendees();
270 if (to) attendeesEv = to->attendees();
271 Attendee *attIn;
272 Attendee *attEv;
273 for ( attIn = attendeesIn.first(); attIn; attIn = attendeesIn.next() ) {
274 for ( attEv = attendeesEv.first(); attEv; attEv = attendeesEv.next() ) {
275 if (attIn->email()==attEv->email()) {
276 //update attendee-info
277 kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl;
278 attEv->setStatus(attIn->status());
279 attEv->setRSVP(false);
280 // better to not update the sequence number with replys
281 //if (ev) ev->setRevision(ev->revision()+1);
282 //if (to) to->setRevision(to->revision()+1);
283 ret = true;
284 }
285 }
286 }
287 }
288 if (ret) deleteTransaction(incidence);
289 return ret;
290}
291
292bool Scheduler::acceptRefresh(IncidenceBase *incidence,ScheduleMessage::Status status)
293{
294 // handled in korganizer's IncomingDialog
295 deleteTransaction(incidence);
296 return false;
297}
298
299bool Scheduler::acceptCounter(IncidenceBase *incidence,ScheduleMessage::Status status)
300{
301 deleteTransaction(incidence);
302 return false;
303}
304
305bool Scheduler::acceptFreeBusy(IncidenceBase *incidence, Method method)
306{
307 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
308
309 QString freeBusyDirName = locateLocal("appdata","freebusy");
310 kdDebug() << "acceptFreeBusy:: freeBusyDirName: " << freeBusyDirName << endl;
311
312 QString from;
313 if(method == Scheduler::Publish) {
314 from = freebusy->organizer();
315 }
316 if((method == Scheduler::Reply) && (freebusy->attendeeCount() == 1)) {
317 Attendee *attendee = freebusy->attendees().first();
318 from = attendee->email();
319 }
320
321 QDir freeBusyDir(freeBusyDirName);
322 if (!freeBusyDir.exists()) {
323 kdDebug() << "Directory " << freeBusyDirName << " does not exist!" << endl;
324 kdDebug() << "Creating directory: " << freeBusyDirName << endl;
325
326 if(!freeBusyDir.mkdir(freeBusyDirName, TRUE)) {
327 kdDebug() << "Could not create directory: " << freeBusyDirName << endl;
328 return false;
329 }
330 }
331
332 QString filename(freeBusyDirName);
333 filename += "/";
334 filename += from;
335 filename += ".ifb";
336 QFile f(filename);
337
338 kdDebug() << "acceptFreeBusy: filename" << filename << endl;
339
340 freebusy->clearAttendees();
341 freebusy->setOrganizer(from);
342
343 QString messageText = mFormat->createScheduleMessage(freebusy, Publish);
344
345 if (!f.open(IO_ReadWrite)) {
346 kdDebug() << "acceptFreeBusy: Can't open:" << filename << " for writing" << endl;
347 return false;
348 }
349 QTextStream t(&f);
350 t << messageText;
351 f.close();
352
353 deleteTransaction(incidence);
354 return true;
355}