]> err.no Git - scalable-opengroupware.org/blob - UI/Scheduler/UIxTaskEditor.m
3f6054829ef4b87283e726b6dff0f66fbe0fd99b
[scalable-opengroupware.org] / UI / Scheduler / UIxTaskEditor.m
1 /* UIxTaskEditor.m - this file is part of SOGo
2  *
3  * Copyright (C) 2007 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file 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, or (at your option)
10  * any later version.
11  *
12  * This file 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; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <NGObjWeb/SoObject.h>
24 #import <NGObjWeb/WORequest.h>
25 #import <NGObjWeb/NSException+HTTP.h>
26 #import <NGExtensions/NSCalendarDate+misc.h>
27
28 #import <NGCards/iCalCalendar.h>
29 #import <NGCards/iCalToDo.h>
30 #import <NGCards/iCalPerson.h>
31
32 #import <SoObjects/SOGo/SOGoUser.h>
33 #import <SoObjects/SOGo/SOGoContentObject.h>
34 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
35 #import <SoObjects/Appointments/SOGoTaskObject.h>
36
37 #import "UIxComponentEditor.h"
38 #import "UIxTaskEditor.h"
39
40 @implementation UIxTaskEditor
41
42 - (id) init
43 {
44   if ((self = [super init]))
45     {
46       taskStartDate = nil;
47       taskDueDate = nil;
48       statusDate = nil;
49       hasStartDate = NO;
50       hasDueDate = NO;
51       status = nil;
52       statusPercent = nil;
53       item = nil;
54       todo = nil;
55     }
56
57   return self;
58 }
59
60 - (void) dealloc
61 {
62   [taskStartDate release];
63   [taskDueDate release];
64   [statusDate release];
65   [status release];
66   [statusPercent release];
67   [super dealloc];
68 }
69
70 /* template values */
71 - (iCalToDo *) todo
72 {
73   return todo;
74 }
75
76 - (NSString *) saveURL
77 {
78   return [NSString stringWithFormat: @"%@/saveAsTask",
79                    [[self clientObject] baseURL]];
80 }
81
82 /* icalendar values */
83 - (void) setTaskStartDate: (NSCalendarDate *) newTaskStartDate
84 {
85   ASSIGN (taskStartDate, newTaskStartDate);
86 }
87
88 - (NSCalendarDate *) taskStartDate
89 {
90   return taskStartDate;
91 }
92
93 - (void) setHasStartDate: (BOOL) newHasStartDate
94 {
95   hasStartDate = newHasStartDate;
96 }
97
98 - (BOOL) hasStartDate
99 {
100   return hasStartDate;
101 }
102
103 - (BOOL) startDateDisabled
104 {
105   return !hasStartDate;
106 }
107
108 - (void) setTaskDueDate: (NSCalendarDate *) newTaskDueDate
109 {
110   ASSIGN (taskDueDate, newTaskDueDate);
111 }
112
113 - (NSCalendarDate *) taskDueDate
114 {
115   return taskDueDate;
116 }
117
118 - (void) setHasDueDate: (BOOL) newHasDueDate
119 {
120   hasDueDate = newHasDueDate;
121 }
122
123 - (BOOL) hasDueDate
124 {
125   return hasDueDate;
126 }
127
128 - (BOOL) dueDateDisabled
129 {
130   return !hasDueDate;
131 }
132
133 - (NSArray *) repeatList
134 {
135   static NSArray *repeatItems = nil;
136
137   if (!repeatItems)
138     {
139       repeatItems = [NSArray arrayWithObjects: @"DAILY",
140                              @"WEEKLY",
141                              @"BI-WEEKLY",
142                              @"EVERY WEEKDAY",
143                              @"MONTHLY",
144                              @"YEARLY",
145                              @"-",
146                              @"CUSTOM",
147                              nil];
148       [repeatItems retain];
149     }
150
151   return repeatItems;
152 }
153
154 - (NSString *) itemRepeatText
155 {
156   NSString *text;
157
158   if ([item isEqualToString: @"-"])
159     text = item;
160   else
161     text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
162
163   return text;
164 }
165
166 - (NSArray *) statusList
167 {
168   static NSArray *statusItems = nil;
169
170   if (!statusItems)
171     {
172       statusItems = [NSArray arrayWithObjects: @"NEEDS-ACTION",
173                              @"IN-PROCESS",
174                              @"COMPLETED",
175                              @"CANCELLED",
176                              nil];
177       [statusItems retain];
178     }
179
180   return statusItems;
181 }
182
183 - (NSString *) itemStatusText
184 {
185   return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
186 }
187
188 - (void) setItem: (NSString *) newItem
189 {
190   item = newItem;
191 }
192
193 - (NSString *) item
194 {
195   return item;
196 }
197
198 - (NSString *) repeat
199 {
200   return @"";
201 }
202
203 - (void) setRepeat: (NSString *) newRepeat
204 {
205 }
206
207 - (NSString *) status
208 {
209   return status;
210 }
211
212 - (void) setStatus: (NSString *) newStatus
213 {
214   status = newStatus;
215 }
216
217 - (void) setStatusDate: (NSCalendarDate *) newStatusDate
218 {
219   ASSIGN (statusDate, newStatusDate);
220 }
221
222 - (NSCalendarDate *) statusDate
223 {
224   return statusDate;
225 }
226
227 - (BOOL) statusDateDisabled
228 {
229   return ![status isEqualToString: @"COMPLETED"];
230 }
231
232 - (BOOL) statusPercentDisabled
233 {
234   return ([status length] == 0
235           || [status isEqualToString: @"CANCELLED"]);
236 }
237
238 - (void) setStatusPercent: (NSString *) newStatusPercent
239 {
240   ASSIGN (statusPercent, newStatusPercent);
241 }
242
243 - (NSString *) statusPercent
244 {
245   return statusPercent;
246 }
247
248 /* actions */
249 - (NSCalendarDate *) newStartDate
250 {
251   NSCalendarDate *newStartDate, *now;
252   int hour;
253   NSTimeZone *timeZone;
254
255   timeZone = [[context activeUser] timeZone];
256
257   newStartDate = [self selectedDate];
258   if ([[self queryParameterForKey: @"hm"] length] == 0)
259     {
260       now = [NSCalendarDate calendarDate];
261       [now setTimeZone: timeZone];
262       if ([now isDateOnSameDay: newStartDate])
263         {
264           hour = [now hourOfDay];
265           if (hour < 8)
266             newStartDate = [now hour: 8 minute: 0];
267           else if (hour > 18)
268             newStartDate = [[now tomorrow] hour: 8 minute: 0];
269           else
270             newStartDate = now;
271         }
272       else
273         newStartDate = [newStartDate hour: 8 minute: 0];
274     }
275
276   return newStartDate;
277 }
278
279 - (id <WOActionResults>) defaultAction
280 {
281   NSCalendarDate *startDate, *dueDate;
282   NSString *duration;
283   unsigned int minutes;
284
285   todo = (iCalToDo *) [[self clientObject] component: NO];
286   if (todo)
287     {
288       startDate = [todo startDate];
289       dueDate = [todo due];
290       hasStartDate = (startDate != nil);
291       hasDueDate = (dueDate != nil);
292       ASSIGN (status, [todo status]);
293       if ([status isEqualToString: @"COMPLETED"])
294         ASSIGN (statusDate, [todo completed]);
295       else
296         ASSIGN (statusDate, [self newStartDate]);
297       ASSIGN (statusPercent, [todo percentComplete]);
298     }
299   else
300     {
301       startDate = [self newStartDate];
302       duration = [self queryParameterForKey:@"dur"];
303       if ([duration length] > 0)
304         minutes = [duration intValue];
305       else
306         minutes = 60;
307       dueDate = [startDate dateByAddingYears: 0 months: 0 days: 0
308                            hours: 0 minutes: minutes seconds: 0];
309       hasStartDate = NO;
310       hasDueDate = NO;
311       ASSIGN (statusDate, [self newStartDate]);
312       ASSIGN (status, @"");
313       ASSIGN (statusPercent, @"");
314     }
315
316   ASSIGN (taskStartDate, startDate);
317   ASSIGN (taskDueDate, dueDate);
318
319   /* here comes the code for initializing repeat, reminder and isAllDay... */
320
321   return self;
322 }
323
324 - (id <WOActionResults>) newAction
325 {
326   NSString *objectId, *method, *uri;
327   id <WOActionResults> result;
328   SOGoAppointmentFolder *co;
329
330   co = [self clientObject];
331   objectId = [co globallyUniqueObjectId];
332   if ([objectId length] > 0)
333     {
334       method = [NSString stringWithFormat:@"%@/%@/editAsTask",
335                          [co soURL], objectId];
336       uri = [self completeHrefForMethod: method];
337       result = [self redirectToLocation: uri];
338     }
339   else
340     result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
341                           reason: @"could not create a unique ID"];
342
343   return result;
344 }
345
346 - (id <WOActionResults>) saveAction
347 {
348   SOGoTaskObject *clientObject;
349   NSString *iCalString;
350
351   clientObject = [self clientObject];
352   iCalString = [[clientObject calendar: NO] versitString];
353   [clientObject saveContentString: iCalString];
354
355   return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
356 }
357
358 - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
359                            inContext: (WOContext*) context
360 {
361   NSString *actionName;
362
363   actionName = [[request requestHandlerPath] lastPathComponent];
364
365   return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
366           && [actionName hasPrefix: @"save"]);
367 }
368
369 - (void) takeValuesFromRequest: (WORequest *) _rq
370                      inContext: (WOContext *) _ctx
371 {
372   SOGoTaskObject *clientObject;
373
374   clientObject = [self clientObject];
375   todo = (iCalToDo *) [clientObject component: YES];
376
377   [super takeValuesFromRequest: _rq inContext: _ctx];
378
379   if (hasStartDate)
380     [todo setStartDate: taskStartDate];
381   else
382     [todo setStartDate: nil];
383
384   if (hasDueDate)
385     [todo setDue: taskDueDate];
386   else
387     [todo setDue: nil];
388
389   if ([status isEqualToString: @"COMPLETED"])
390     [todo setCompleted: statusDate];
391   else
392     [todo setCompleted: nil];
393   if ([status length] > 0)
394     {
395       [todo setStatus: status];
396       [todo setPercentComplete: statusPercent];
397     }
398   else
399     {
400       [todo setStatus: @""];
401       [todo setPercentComplete: @""];
402     }
403 }
404
405 // TODO: add tentatively
406
407 - (id) acceptOrDeclineAction: (BOOL) _accept
408 {
409   [[self clientObject] changeParticipationStatus:
410                          _accept ? @"ACCEPTED" : @"DECLINED"];
411
412   return self;
413 }
414
415 - (id) acceptAction
416 {
417   return [self acceptOrDeclineAction: YES];
418 }
419
420 - (id) declineAction
421 {
422   return [self acceptOrDeclineAction: NO];
423 }
424
425 - (id) changeStatusAction
426 {
427   SOGoTaskObject *clientObject;
428   NSString *newStatus, *iCalString;
429
430   clientObject = [self clientObject];
431   todo = (iCalToDo *) [clientObject component: NO];
432   if (todo)
433     {
434       newStatus = [self queryParameterForKey: @"status"];
435       if ([newStatus intValue])
436         [todo setCompleted: [NSCalendarDate date]];
437       else
438         {
439           [todo setCompleted: nil];
440           [todo setPercentComplete: @"0"];
441           [todo setStatus: @"IN-PROCESS"];
442         }
443
444       iCalString = [[clientObject calendar: NO] versitString];
445       [clientObject saveContentString: iCalString];
446     }
447
448   return self;
449 }
450
451 @end