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>
28 #import <Foundation/NSValue.h>
30 #import <NGObjWeb/WOContext.h>
31 #import <NGObjWeb/WOContext+SoObjects.h>
32 #import <NGObjWeb/WORequest.h>
33 #import <NGObjWeb/WOResponse.h>
34 #import <NGExtensions/NSCalendarDate+misc.h>
36 #import <SoObjects/SOGo/SOGoUser.h>
37 #import <SoObjects/SOGo/SOGoDateFormatter.h>
38 #import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
39 #import <SoObjects/SOGo/NSArray+Utilities.h>
40 #import <SoObjects/SOGo/NSObject+Utilities.h>
41 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
42 #import <SoObjects/Appointments/SOGoAppointmentFolders.h>
44 #import <UI/Common/WODirectAction+SOGo.h>
46 #import "NSArray+Scheduler.h"
48 #import "UIxCalListingActions.h"
50 @implementation UIxCalListingActions
52 - (id) initWithRequest: (WORequest *) newRequest
56 if ((self = [super initWithRequest: newRequest]))
58 componentsData = [NSMutableDictionary new];
61 ASSIGN (request, newRequest);
62 user = [[self context] activeUser];
63 dateFormatter = [user dateFormatterInContext: context];
64 ASSIGN (userTimeZone, [user timeZone]);
72 [dateFormatter release];
74 [componentsData release];
77 [userTimeZone release];
81 - (void) _setupDatesWithPopup: (NSString *) popupValue
82 andUserTZ: (NSTimeZone *) userTZ
84 NSCalendarDate *newDate;
87 if ([popupValue isEqualToString: @"view_today"])
89 newDate = [NSCalendarDate calendarDate];
90 [newDate setTimeZone: userTZ];
91 startDate = [newDate beginOfDay];
92 endDate = [newDate endOfDay];
94 else if ([popupValue isEqualToString: @"view_all"])
99 else if ([popupValue isEqualToString: @"view_next7"])
101 newDate = [NSCalendarDate calendarDate];
102 [newDate setTimeZone: userTZ];
103 startDate = [newDate beginOfDay];
104 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 6] endOfDay];
106 else if ([popupValue isEqualToString: @"view_next14"])
108 newDate = [NSCalendarDate calendarDate];
109 [newDate setTimeZone: userTZ];
110 startDate = [newDate beginOfDay];
111 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 13] endOfDay];
113 else if ([popupValue isEqualToString: @"view_next31"])
115 newDate = [NSCalendarDate calendarDate];
116 [newDate setTimeZone: userTZ];
117 startDate = [newDate beginOfDay];
118 endDate = [[startDate dateByAddingYears: 0 months: 0 days: 30] endOfDay];
120 else if ([popupValue isEqualToString: @"view_thismonth"])
122 newDate = [NSCalendarDate calendarDate];
123 [newDate setTimeZone: userTZ];
124 startDate = [[newDate firstDayOfMonth] beginOfDay];
125 endDate = [[newDate lastDayOfMonth] endOfDay];
127 else if ([popupValue isEqualToString: @"view_future"])
129 newDate = [NSCalendarDate calendarDate];
130 [newDate setTimeZone: userTZ];
131 startDate = [newDate beginOfDay];
132 endDate = [NSCalendarDate distantFuture];
134 else if ([popupValue isEqualToString: @"view_selectedday"])
136 param = [request formValueForKey: @"day"];
137 if ([param length] > 0)
138 startDate = [[NSCalendarDate dateFromShortDateString: param
139 andShortTimeString: nil
140 inTimeZone: userTZ] beginOfDay];
143 newDate = [NSCalendarDate calendarDate];
144 [newDate setTimeZone: userTZ];
145 startDate = [newDate beginOfDay];
147 endDate = [startDate endOfDay];
151 - (void) _setupContext
157 user = [context activeUser];
158 userLogin = [user login];
159 userTZ = [user timeZone];
161 param = [request formValueForKey: @"filterpopup"];
162 if ([param length] > 0)
163 [self _setupDatesWithPopup: param andUserTZ: userTZ];
166 param = [request formValueForKey: @"sd"];
167 if ([param length] > 0)
168 startDate = [[NSCalendarDate dateFromShortDateString: param
169 andShortTimeString: nil
170 inTimeZone: userTZ] beginOfDay];
174 param = [request formValueForKey: @"ed"];
175 if ([param length] > 0)
176 endDate = [[NSCalendarDate dateFromShortDateString: param
177 andShortTimeString: nil
178 inTimeZone: userTZ] endOfDay];
184 - (void) _updatePrivacyInComponent: (NSMutableDictionary *) component
185 fromFolder: (SOGoAppointmentFolder *) folder
188 NSString *roleString;
190 privacyFlag = [[component objectForKey: @"classification"] intValue];
191 roleString = [folder roleForComponentsWithAccessClass: privacyFlag
193 if ([roleString isEqualToString: @"ComponentDAndTViewer"])
195 [component setObject: @"" forKey: @"c_title"];
196 [component setObject: @"" forKey: @"c_location"];
200 - (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder
201 withClientObject: (SOGoAppointmentFolder *) clientObject
203 SOGoAppointmentFolder *aptFolder;
204 NSArray *folderParts;
206 if ([folder isEqualToString: @"/"])
207 aptFolder = clientObject;
210 folderParts = [folder componentsSeparatedByString: @":"];
212 = [clientObject lookupCalendarFolderForUID:
213 [folderParts objectAtIndex: 0]];
219 - (NSArray *) _fetchFields: (NSArray *) fields
220 forComponentOfType: (NSString *) component
222 NSEnumerator *folders, *currentInfos;
223 SOGoAppointmentFolder *currentFolder;
224 NSMutableDictionary *infos, *currentInfo, *newInfo;
225 NSString *owner, *uid;
227 SOGoAppointmentFolders *clientObject;
229 marker = [NSNull null];
231 infos = [NSMutableDictionary dictionary];
232 clientObject = [self clientObject];
234 folders = [[clientObject subFolders] objectEnumerator];
235 currentFolder = [folders nextObject];
236 while (currentFolder)
238 if ([currentFolder isActive])
240 owner = [currentFolder ownerInContext: context];
241 currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
243 component: component] objectEnumerator];
244 newInfo = [currentInfos nextObject];
247 uid = [newInfo objectForKey: @"c_uid"];
248 currentInfo = [infos objectForKey: uid];
250 || [owner isEqualToString: userLogin])
252 [self _updatePrivacyInComponent: newInfo
253 fromFolder: currentFolder];
254 [newInfo setObject: [currentFolder nameInContainer]
255 forKey: @"c_folder"];
256 // [newInfo setObject: owner forKey: @"c_owner"];
257 [infos setObject: [newInfo objectsForKeys: fields
258 notFoundMarker: marker]
261 newInfo = [currentInfos nextObject];
264 currentFolder = [folders nextObject];
267 return [infos allValues];
270 - (WOResponse *) _responseWithData: (NSArray *) data
272 WOResponse *response;
274 response = [self responseWithStatus: 200];
275 [response setHeader: @"text/plain; charset=utf-8"
276 forKey: @"content-type"];
277 [response appendContentString: [data jsonRepresentation]];
282 - (NSString *) _formattedDateForSeconds: (unsigned int) seconds
283 forAllDay: (BOOL) forAllDay
285 NSCalendarDate *date;
286 NSString *formattedDate;
288 date = [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
289 [date setTimeZone: userTimeZone];
291 formattedDate = [dateFormatter formattedDate: date];
293 formattedDate = [dateFormatter formattedDateAndTime: date];
295 return formattedDate;
298 - (WOResponse *) eventsListAction
300 NSArray *fields, *oldEvent;
301 NSEnumerator *events;
302 NSMutableArray *newEvents, *newEvent;
303 unsigned int interval;
306 [self _setupContext];
308 newEvents = [NSMutableArray array];
309 fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
310 @"c_title", @"c_startdate", @"c_enddate", @"c_location",
312 events = [[self _fetchFields: fields
313 forComponentOfType: @"vevent"] objectEnumerator];
314 oldEvent = [events nextObject];
317 newEvent = [NSMutableArray arrayWithArray: oldEvent];
318 isAllDay = [[oldEvent objectAtIndex: 7] boolValue];
319 interval = [[oldEvent objectAtIndex: 4] intValue];
320 [newEvent addObject: [self _formattedDateForSeconds: interval
321 forAllDay: isAllDay]];
322 interval = [[oldEvent objectAtIndex: 5] intValue];
323 [newEvent addObject: [self _formattedDateForSeconds: interval
324 forAllDay: isAllDay]];
325 [newEvents addObject: newEvent];
327 oldEvent = [events nextObject];
329 [newEvents sortUsingSelector: @selector (compareEventsAscending:)];
331 return [self _responseWithData: newEvents];
334 - (NSString *) _getStatusClassForStatusCode: (int) statusCode
335 andEndDateStamp: (unsigned int) endDateStamp
337 NSCalendarDate *taskDate, *now;
338 NSString *statusClass;
341 statusClass = @"completed";
346 now = [NSCalendarDate calendarDate];
348 = [NSCalendarDate dateWithTimeIntervalSince1970: endDateStamp];
349 if ([taskDate earlierDate: now] == taskDate)
350 statusClass = @"overdue";
353 if ([taskDate isToday])
354 statusClass = @"duetoday";
356 statusClass = @"duelater";
360 statusClass = @"duelater";
366 - (WOResponse *) tasksListAction
369 NSMutableArray *filteredTasks, *filteredTask;
371 NSArray *fields, *task;
373 unsigned int endDateStamp;
374 NSString *statusFlag;
376 filteredTasks = [NSMutableArray array];
378 [self _setupContext];
380 fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
381 @"c_title", @"c_enddate", nil];
383 tasks = [[self _fetchFields: fields
384 forComponentOfType: @"vtodo"] objectEnumerator];
385 showCompleted = [[request formValueForKey: @"show-completed"] intValue];
387 task = [tasks nextObject];
390 statusCode = [[task objectAtIndex: 2] intValue];
391 if (statusCode != 1 || showCompleted)
393 filteredTask = [NSMutableArray arrayWithArray: task];
394 endDateStamp = [[task objectAtIndex: 4] intValue];
395 statusFlag = [self _getStatusClassForStatusCode: statusCode
396 andEndDateStamp: endDateStamp];
397 [filteredTask addObject: statusFlag];
398 [filteredTasks addObject: filteredTask];
400 task = [tasks nextObject];
402 [filteredTasks sortUsingSelector: @selector (compareTasksAscending:)];
404 return [self _responseWithData: filteredTasks];
407 // - (BOOL) shouldDisplayCurrentTask
412 // = [[self queryParameterForKey: @"show-completed"] intValue];
413 // knowsToShow = YES;
416 // return ([[currentTask objectForKey: @"status"] intValue] != 1
417 // || showCompleted);
420 // - (BOOL) shouldShowCompletedTasks
425 // = [[self queryParameterForKey: @"show-completed"] intValue];
426 // knowsToShow = YES;
429 // return showCompleted;