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 *newInfo;
225 NSMutableArray *infos;
227 SOGoAppointmentFolders *clientObject;
229 marker = [NSNull null];
231 clientObject = [self clientObject];
233 folders = [[clientObject subFolders] objectEnumerator];
234 currentFolder = [folders nextObject];
236 infos = [NSMutableArray array];
237 while (currentFolder)
239 if ([currentFolder isActive])
241 currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
243 component: component] objectEnumerator];
245 while ((newInfo = [currentInfos nextObject]))
247 [self _updatePrivacyInComponent: newInfo
248 fromFolder: currentFolder];
249 [newInfo setObject: [currentFolder nameInContainer]
250 forKey: @"c_folder"];
252 [infos addObject: [newInfo objectsForKeys: fields
253 notFoundMarker: marker]];
256 currentFolder = [folders nextObject];
262 - (WOResponse *) _responseWithData: (NSArray *) data
264 WOResponse *response;
266 response = [self responseWithStatus: 200];
267 [response setHeader: @"text/plain; charset=utf-8"
268 forKey: @"content-type"];
269 [response appendContentString: [data jsonRepresentation]];
274 - (NSString *) _formattedDateForSeconds: (unsigned int) seconds
275 forAllDay: (BOOL) forAllDay
277 NSCalendarDate *date;
278 NSString *formattedDate;
280 date = [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
281 [date setTimeZone: userTimeZone];
283 formattedDate = [dateFormatter formattedDate: date];
285 formattedDate = [dateFormatter formattedDateAndTime: date];
287 return formattedDate;
290 - (WOResponse *) eventsListAction
292 NSArray *fields, *oldEvent;
293 NSEnumerator *events;
294 NSMutableArray *newEvents, *newEvent;
295 unsigned int interval;
298 [self _setupContext];
300 newEvents = [NSMutableArray array];
301 fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
302 @"c_title", @"c_startdate", @"c_enddate", @"c_location",
304 events = [[self _fetchFields: fields
305 forComponentOfType: @"vevent"] objectEnumerator];
306 oldEvent = [events nextObject];
309 newEvent = [NSMutableArray arrayWithArray: oldEvent];
310 isAllDay = [[oldEvent objectAtIndex: 7] boolValue];
311 interval = [[oldEvent objectAtIndex: 4] intValue];
312 [newEvent addObject: [self _formattedDateForSeconds: interval
313 forAllDay: isAllDay]];
314 interval = [[oldEvent objectAtIndex: 5] intValue];
315 [newEvent addObject: [self _formattedDateForSeconds: interval
316 forAllDay: isAllDay]];
317 [newEvents addObject: newEvent];
319 oldEvent = [events nextObject];
321 [newEvents sortUsingSelector: @selector (compareEventsAscending:)];
323 return [self _responseWithData: newEvents];
326 - (NSString *) _getStatusClassForStatusCode: (int) statusCode
327 andEndDateStamp: (unsigned int) endDateStamp
329 NSCalendarDate *taskDate, *now;
330 NSString *statusClass;
333 statusClass = @"completed";
338 now = [NSCalendarDate calendarDate];
340 = [NSCalendarDate dateWithTimeIntervalSince1970: endDateStamp];
341 if ([taskDate earlierDate: now] == taskDate)
342 statusClass = @"overdue";
345 if ([taskDate isToday])
346 statusClass = @"duetoday";
348 statusClass = @"duelater";
352 statusClass = @"duelater";
358 - (WOResponse *) tasksListAction
361 NSMutableArray *filteredTasks, *filteredTask;
363 NSArray *fields, *task;
365 unsigned int endDateStamp;
366 NSString *statusFlag;
368 filteredTasks = [NSMutableArray array];
370 [self _setupContext];
372 fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
373 @"c_title", @"c_enddate", nil];
375 tasks = [[self _fetchFields: fields
376 forComponentOfType: @"vtodo"] objectEnumerator];
377 showCompleted = [[request formValueForKey: @"show-completed"] intValue];
379 task = [tasks nextObject];
382 statusCode = [[task objectAtIndex: 2] intValue];
383 if (statusCode != 1 || showCompleted)
385 filteredTask = [NSMutableArray arrayWithArray: task];
386 endDateStamp = [[task objectAtIndex: 4] intValue];
387 statusFlag = [self _getStatusClassForStatusCode: statusCode
388 andEndDateStamp: endDateStamp];
389 [filteredTask addObject: statusFlag];
390 [filteredTasks addObject: filteredTask];
392 task = [tasks nextObject];
394 [filteredTasks sortUsingSelector: @selector (compareTasksAscending:)];
396 return [self _responseWithData: filteredTasks];
399 // - (BOOL) shouldDisplayCurrentTask
404 // = [[self queryParameterForKey: @"show-completed"] intValue];
405 // knowsToShow = YES;
408 // return ([[currentTask objectForKey: @"status"] intValue] != 1
409 // || showCompleted);
412 // - (BOOL) shouldShowCompletedTasks
417 // = [[self queryParameterForKey: @"show-completed"] intValue];
418 // knowsToShow = YES;
421 // return showCompleted;