1 /* UIxCalListingActions.m - this file is part of SOGo
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
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)
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.
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.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSDictionary.h>
25 #import <Foundation/NSEnumerator.h>
26 #import <Foundation/NSNull.h>
27 #import <Foundation/NSString.h>
29 #import <NGObjWeb/WOContext.h>
30 #import <NGObjWeb/WOContext+SoObjects.h>
31 #import <NGObjWeb/WORequest.h>
32 #import <NGObjWeb/WOResponse.h>
33 #import <NGExtensions/NSCalendarDate+misc.h>
35 #import <SoObjects/SOGo/SOGoUser.h>
36 #import <SoObjects/SOGo/SOGoDateFormatter.h>
37 #import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
38 #import <SoObjects/SOGo/NSArray+Utilities.h>
39 #import <SoObjects/SOGo/NSObject+Utilities.h>
40 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
42 #import "NSArray+Scheduler.h"
44 #import "UIxCalListingActions.h"
46 @implementation UIxCalListingActions
48 - (id) initWithRequest: (WORequest *) newRequest
52 if ((self = [super initWithRequest: newRequest]))
54 componentsData = [NSMutableDictionary new];
57 ASSIGN (request, newRequest);
58 user = [[self context] activeUser];
59 dateFormatter = [user dateFormatterInContext: context];
60 ASSIGN (userTimeZone, [user timeZone]);
68 [dateFormatter release];
70 [componentsData release];
73 [userTimeZone release];
77 - (void) _setupDatesWithPopup: (NSString *) popupValue
78 andUserTZ: (NSTimeZone *) userTZ
80 NSCalendarDate *newDate;
83 if ([popupValue isEqualToString: @"view_today"])
85 newDate = [NSCalendarDate calendarDate];
86 [newDate setTimeZone: userTZ];
87 startDate = [newDate beginOfDay];
88 endDate = [newDate endOfDay];
90 else if ([popupValue isEqualToString: @"view_all"])
95 else if ([popupValue isEqualToString: @"view_next7"])
97 newDate = [NSCalendarDate calendarDate];
98 [newDate setTimeZone: userTZ];
99 startDate = [newDate beginOfDay];
100 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 6] endOfDay];
102 else if ([popupValue isEqualToString: @"view_next14"])
104 newDate = [NSCalendarDate calendarDate];
105 [newDate setTimeZone: userTZ];
106 startDate = [newDate beginOfDay];
107 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 13] endOfDay];
109 else if ([popupValue isEqualToString: @"view_next31"])
111 newDate = [NSCalendarDate calendarDate];
112 [newDate setTimeZone: userTZ];
113 startDate = [newDate beginOfDay];
114 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 30] endOfDay];
116 else if ([popupValue isEqualToString: @"view_thismonth"])
118 newDate = [NSCalendarDate calendarDate];
119 [newDate setTimeZone: userTZ];
120 startDate = [[newDate firstDayOfMonth] beginOfDay];
121 endDate = [[newDate lastDayOfMonth] endOfDay];
123 else if ([popupValue isEqualToString: @"view_future"])
125 newDate = [NSCalendarDate calendarDate];
126 [newDate setTimeZone: userTZ];
127 startDate = [newDate beginOfDay];
128 endDate = [NSCalendarDate distantFuture];
130 else if ([popupValue isEqualToString: @"view_selectedday"])
132 param = [request formValueForKey: @"day"];
133 if ([param length] > 0)
134 startDate = [[NSCalendarDate dateFromShortDateString: param
135 andShortTimeString: nil
136 inTimeZone: userTZ] beginOfDay];
139 newDate = [NSCalendarDate calendarDate];
140 [newDate setTimeZone: userTZ];
141 startDate = [newDate beginOfDay];
143 endDate = [startDate endOfDay];
147 - (void) _setupContext
153 user = [context activeUser];
154 userLogin = [user login];
155 userTZ = [user timeZone];
157 param = [request formValueForKey: @"filterpopup"];
158 if ([param length] > 0)
159 [self _setupDatesWithPopup: param andUserTZ: userTZ];
162 param = [request formValueForKey: @"sd"];
163 if ([param length] > 0)
164 startDate = [[NSCalendarDate dateFromShortDateString: param
165 andShortTimeString: nil
166 inTimeZone: userTZ] beginOfDay];
170 param = [request formValueForKey: @"ed"];
171 if ([param length] > 0)
172 endDate = [[NSCalendarDate dateFromShortDateString: param
173 andShortTimeString: nil
174 inTimeZone: userTZ] endOfDay];
180 - (void) _updatePrivacyInComponent: (NSMutableDictionary *) component
181 fromFolder: (SOGoAppointmentFolder *) folder
184 NSString *roleString;
186 privacyFlag = [[component objectForKey: @"classification"] intValue];
187 roleString = [folder roleForComponentsWithAccessClass: privacyFlag
189 if ([roleString isEqualToString: @"ComponentDAndTViewer"])
191 [component setObject: @"" forKey: @"title"];
192 [component setObject: @"" forKey: @"location"];
196 - (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder
197 withClientObject: (SOGoAppointmentFolder *) clientObject
199 SOGoAppointmentFolder *aptFolder;
200 NSArray *folderParts;
202 if ([folder isEqualToString: @"/"])
203 aptFolder = clientObject;
206 folderParts = [folder componentsSeparatedByString: @":"];
208 = [clientObject lookupCalendarFolderForUID:
209 [folderParts objectAtIndex: 0]];
215 - (NSArray *) _activeCalendarFolders
217 NSMutableArray *activeFolders;
218 NSEnumerator *folders;
219 NSDictionary *currentFolderDict;
220 SOGoAppointmentFolder *currentFolder, *clientObject;
222 activeFolders = [NSMutableArray new];
223 [activeFolders autorelease];
225 clientObject = [self clientObject];
227 folders = [[clientObject calendarFolders] objectEnumerator];
228 currentFolderDict = [folders nextObject];
229 while (currentFolderDict)
231 if ([[currentFolderDict objectForKey: @"active"] boolValue])
234 = [self _aptFolder: [currentFolderDict objectForKey: @"folder"]
235 withClientObject: clientObject];
236 [activeFolders addObject: currentFolder];
239 currentFolderDict = [folders nextObject];
242 return activeFolders;
245 - (NSArray *) _fetchFields: (NSArray *) fields
246 forComponentOfType: (NSString *) component
248 NSEnumerator *folders, *currentInfos;
249 SOGoAppointmentFolder *currentFolder;
250 NSMutableDictionary *infos, *currentInfo, *newInfo;
251 NSString *owner, *uid;
254 marker = [NSNull null];
256 infos = [NSMutableDictionary dictionary];
257 folders = [[self _activeCalendarFolders] objectEnumerator];
258 currentFolder = [folders nextObject];
259 while (currentFolder)
261 owner = [currentFolder ownerInContext: context];
262 currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
264 component: component] objectEnumerator];
265 newInfo = [currentInfos nextObject];
268 uid = [newInfo objectForKey: @"uid"];
269 currentInfo = [infos objectForKey: uid];
271 || [owner isEqualToString: userLogin])
273 [self _updatePrivacyInComponent: newInfo
274 fromFolder: currentFolder];
275 [newInfo setObject: owner forKey: @"owner"];
276 [infos setObject: [newInfo objectsForKeys: fields
277 notFoundMarker: marker]
280 newInfo = [currentInfos nextObject];
282 currentFolder = [folders nextObject];
285 return [infos allValues];
288 - (WOResponse *) _responseWithData: (NSArray *) data
290 WOResponse *response;
292 response = [context response];
293 [response setHeader: @"text/plain; charset=utf-8"
294 forKey: @"content-type"];
295 [response setStatus: 200];
296 [response appendContentString: [data jsonRepresentation]];
301 - (NSString *) _formattedDateForSeconds: (unsigned int) seconds
302 forAllDay: (BOOL) forAllDay
304 NSCalendarDate *date;
305 NSString *formattedDate;
307 date = [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
308 [date setTimeZone: userTimeZone];
310 formattedDate = [dateFormatter formattedDate: date];
312 formattedDate = [dateFormatter formattedDateAndTime: date];
314 return formattedDate;
317 - (WOResponse *) eventsListAction
319 NSArray *fields, *oldEvent;
320 NSEnumerator *events;
321 NSMutableArray *newEvents, *newEvent;
322 unsigned int interval;
325 [self _setupContext];
327 newEvents = [NSMutableArray array];
328 fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status",
329 @"title", @"startdate", @"enddate", @"location",
331 events = [[self _fetchFields: fields
332 forComponentOfType: @"vevent"] objectEnumerator];
333 oldEvent = [events nextObject];
336 newEvent = [NSMutableArray arrayWithArray: oldEvent];
337 isAllDay = [[oldEvent objectAtIndex: 7] boolValue];
338 interval = [[oldEvent objectAtIndex: 4] intValue];
339 [newEvent addObject: [self _formattedDateForSeconds: interval
340 forAllDay: isAllDay]];
341 interval = [[oldEvent objectAtIndex: 5] intValue];
342 [newEvent addObject: [self _formattedDateForSeconds: interval
343 forAllDay: isAllDay]];
344 [newEvents addObject: newEvent];
346 oldEvent = [events nextObject];
348 [newEvents sortUsingSelector: @selector (compareEventsAscending:)];
350 return [self _responseWithData: newEvents];
353 - (NSString *) _getStatusClassForStatusCode: (int) statusCode
354 andEndDateStamp: (unsigned int) endDateStamp
356 NSCalendarDate *taskDate, *now;
357 NSString *statusClass;
360 statusClass = @"completed";
365 now = [NSCalendarDate calendarDate];
367 = [NSCalendarDate dateWithTimeIntervalSince1970: endDateStamp];
368 if ([taskDate earlierDate: now] == taskDate)
369 statusClass = @"overdue";
372 if ([taskDate isToday])
373 statusClass = @"duetoday";
375 statusClass = @"duelater";
379 statusClass = @"duelater";
385 - (WOResponse *) tasksListAction
388 NSMutableArray *filteredTasks, *filteredTask;
390 NSArray *fields, *task;
392 unsigned int endDateStamp;
393 NSString *statusFlag;
395 filteredTasks = [NSMutableArray array];
397 [self _setupContext];
399 fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status",
400 @"title", @"enddate", nil];
402 tasks = [[self _fetchFields: fields
403 forComponentOfType: @"vtodo"] objectEnumerator];
404 showCompleted = [[request formValueForKey: @"show-completed"] intValue];
406 task = [tasks nextObject];
409 statusCode = [[task objectAtIndex: 2] intValue];
410 if (statusCode != 1 || showCompleted)
412 filteredTask = [NSMutableArray arrayWithArray: task];
413 endDateStamp = [[task objectAtIndex: 4] intValue];
414 statusFlag = [self _getStatusClassForStatusCode: statusCode
415 andEndDateStamp: endDateStamp];
416 [filteredTask addObject: statusFlag];
417 [filteredTasks addObject: filteredTask];
419 task = [tasks nextObject];
421 [filteredTasks sortUsingSelector: @selector (compareTasksAscending:)];
423 return [self _responseWithData: filteredTasks];
426 // - (BOOL) shouldDisplayCurrentTask
431 // = [[self queryParameterForKey: @"show-completed"] intValue];
432 // knowsToShow = YES;
435 // return ([[currentTask objectForKey: @"status"] intValue] != 1
436 // || showCompleted);
439 // - (BOOL) shouldShowCompletedTasks
444 // = [[self queryParameterForKey: @"show-completed"] intValue];
445 // knowsToShow = YES;
448 // return showCompleted;