2007-03-29 20:08:40 +02:00
|
|
|
/* UIxCalendarSelector.m - this file is part of SOGo
|
|
|
|
*
|
2016-04-27 21:25:01 +02:00
|
|
|
* Copyright (C) 2007-2016 Inverse inc.
|
2007-03-29 20:08:40 +02:00
|
|
|
*
|
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
#import <Foundation/NSValue.h>
|
2007-03-29 20:08:40 +02:00
|
|
|
|
2008-01-15 22:45:48 +01:00
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
#import <SOGo/NSDictionary+Utilities.h>
|
2015-12-10 17:11:22 +01:00
|
|
|
#import <SOGo/SOGoPermissions.h>
|
2015-01-26 21:36:55 +01:00
|
|
|
#import <SOGo/SOGoSystemDefaults.h>
|
2007-11-12 22:20:18 +01:00
|
|
|
|
2008-01-15 22:45:48 +01:00
|
|
|
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
2007-11-12 22:20:18 +01:00
|
|
|
#import <SoObjects/SOGo/SOGoUser.h>
|
2016-04-27 21:25:01 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoUserSettings.h>
|
2007-11-12 22:20:18 +01:00
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
#import <Appointments/SOGoAppointmentFolders.h>
|
2015-01-26 21:36:55 +01:00
|
|
|
#import <Appointments/SOGoWebAppointmentFolder.h>
|
2007-03-29 20:08:40 +02:00
|
|
|
|
|
|
|
#import "UIxCalendarSelector.h"
|
|
|
|
|
2008-04-22 19:16:37 +02:00
|
|
|
static inline unsigned int
|
|
|
|
_intValueFromHexChar (unichar hexChar)
|
|
|
|
{
|
|
|
|
unichar base;
|
|
|
|
|
|
|
|
if (hexChar >= '0' && hexChar <= '9')
|
|
|
|
base = '0';
|
|
|
|
else if (hexChar >= 'A' && hexChar <= 'F')
|
|
|
|
base = 'A' - 10;
|
|
|
|
else
|
|
|
|
base = 'a' - 10;
|
|
|
|
|
|
|
|
return (hexChar - base);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
_intValueFromHex (NSString *hexString)
|
|
|
|
{
|
|
|
|
unsigned int value, count, max;
|
|
|
|
|
|
|
|
value = 0;
|
|
|
|
max = [hexString length];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
value = (value * 16
|
|
|
|
+ _intValueFromHexChar([hexString characterAtIndex: count]));
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2007-03-29 20:08:40 +02:00
|
|
|
@implementation UIxCalendarSelector
|
|
|
|
|
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
2007-09-15 00:01:02 +02:00
|
|
|
calendars = nil;
|
|
|
|
currentCalendar = nil;
|
2007-03-29 20:08:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
2007-09-15 00:01:02 +02:00
|
|
|
[calendars release];
|
|
|
|
[currentCalendar release];
|
2007-03-29 20:08:40 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2015-01-26 21:36:55 +01:00
|
|
|
- (BOOL) isPublicAccessEnabled
|
|
|
|
{
|
|
|
|
return [[SOGoSystemDefaults sharedSystemDefaults] enablePublicAccess];
|
|
|
|
}
|
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
- (NSArray *) calendars
|
2007-03-29 20:08:40 +02:00
|
|
|
{
|
2016-04-27 21:25:01 +02:00
|
|
|
BOOL objectCreator, objectEraser, reloadOnLogin, synchronize, dirty;
|
|
|
|
NSArray *folders, *allACLs;
|
|
|
|
NSMutableArray *sortedFolders, *sortedFolderNames;
|
|
|
|
NSMutableDictionary *moduleSettings, *calendar, *notifications, *urls, *acls;
|
2015-01-26 21:36:55 +01:00
|
|
|
NSNumber *isActive, *fActiveTasks;
|
2016-04-27 21:25:01 +02:00
|
|
|
NSString *userLogin, *folderName, *fDisplayName, *owner;
|
2016-06-09 19:26:22 +02:00
|
|
|
NSInteger count, index, max;
|
2007-09-15 00:01:02 +02:00
|
|
|
SOGoAppointmentFolder *folder;
|
2015-12-10 17:11:22 +01:00
|
|
|
SOGoAppointmentFolders *co;
|
2016-04-27 21:25:01 +02:00
|
|
|
SOGoUser *activeUser;
|
|
|
|
SOGoUserSettings *us;
|
2015-12-10 17:11:22 +01:00
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
if (!calendars)
|
2007-03-29 20:08:40 +02:00
|
|
|
{
|
2015-12-10 17:11:22 +01:00
|
|
|
co = [self clientObject];
|
2016-04-27 21:25:01 +02:00
|
|
|
activeUser = [context activeUser];
|
|
|
|
userLogin = [activeUser login];
|
2015-12-10 17:11:22 +01:00
|
|
|
folders = [co subFolders];
|
2016-04-27 21:25:01 +02:00
|
|
|
|
|
|
|
// Sort calendars according to user settings
|
|
|
|
dirty = NO;
|
|
|
|
us = [activeUser userSettings];
|
|
|
|
moduleSettings = [us objectForKey: [co nameInContainer]];
|
|
|
|
sortedFolders = [NSMutableArray arrayWithArray: [moduleSettings objectForKey: @"FoldersOrder"]];
|
|
|
|
|
2016-06-09 19:26:22 +02:00
|
|
|
// We first start by replacing folder names with actual SOGoFolder instances
|
2015-12-10 17:11:22 +01:00
|
|
|
max = [folders count];
|
|
|
|
for (count = 0; count < max; count++)
|
2015-01-26 21:36:55 +01:00
|
|
|
{
|
2015-12-10 17:11:22 +01:00
|
|
|
folder = [folders objectAtIndex: count];
|
2016-04-27 21:25:01 +02:00
|
|
|
folderName = [folder nameInContainer];
|
|
|
|
index = [sortedFolders indexOfObject: folderName];
|
|
|
|
if (index == NSNotFound)
|
|
|
|
{
|
|
|
|
// Calendar is missing from user's "FoldersOrder" setting; add it
|
|
|
|
dirty = YES;
|
|
|
|
[sortedFolders addObject: folder];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
[sortedFolders replaceObjectAtIndex: index withObject: folder];
|
|
|
|
}
|
|
|
|
|
2016-06-09 19:26:22 +02:00
|
|
|
// We then build our sorted folder list names, removing any deleted folders
|
2016-04-27 21:25:01 +02:00
|
|
|
max = [sortedFolders count];
|
|
|
|
sortedFolderNames = [NSMutableArray arrayWithCapacity: max];
|
2016-06-09 19:26:22 +02:00
|
|
|
for (count = max-1; count >= 0; count--)
|
2016-04-27 21:25:01 +02:00
|
|
|
{
|
|
|
|
if ([[sortedFolders objectAtIndex: count] isKindOfClass: [NSString class]])
|
|
|
|
{
|
|
|
|
// Calendar no longer exists; remove it from user's "FoldersOrder" setting
|
|
|
|
dirty = YES;
|
|
|
|
[sortedFolders removeObjectAtIndex: count];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
folder = [sortedFolders objectAtIndex: count];
|
|
|
|
folderName = [folder nameInContainer];
|
|
|
|
[sortedFolderNames addObject: folderName];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dirty)
|
|
|
|
{
|
|
|
|
// Synchronize user's settings
|
|
|
|
[moduleSettings setObject: sortedFolderNames forKey: @"FoldersOrder"];
|
|
|
|
[us synchronize];
|
|
|
|
}
|
|
|
|
|
|
|
|
max = [folders count];
|
2016-06-09 16:42:28 +02:00
|
|
|
|
|
|
|
DESTROY(calendars);
|
2016-04-27 21:25:01 +02:00
|
|
|
calendars = [[NSMutableArray alloc] initWithCapacity: max];
|
2016-06-09 16:42:28 +02:00
|
|
|
|
2016-04-27 21:25:01 +02:00
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
folder = [sortedFolders objectAtIndex: count];
|
2015-12-10 17:11:22 +01:00
|
|
|
owner = [folder ownerInContext: context];
|
|
|
|
calendar = [NSMutableDictionary dictionary];
|
|
|
|
folderName = [folder nameInContainer];
|
|
|
|
fDisplayName = [folder displayName];
|
|
|
|
if (fDisplayName == nil)
|
|
|
|
fDisplayName = @"";
|
|
|
|
if ([fDisplayName isEqualToString: [co defaultFolderName]])
|
|
|
|
fDisplayName = [self labelForKey: fDisplayName];
|
|
|
|
fActiveTasks = [folder activeTasks];
|
|
|
|
|
|
|
|
[calendar setObject: folderName forKey: @"id"];
|
|
|
|
[calendar setObject: fDisplayName forKey: @"name"];
|
|
|
|
[calendar setObject: [folder calendarColor] forKey: @"color"];
|
|
|
|
isActive = [NSNumber numberWithBool: [folder isActive]];
|
|
|
|
[calendar setObject: isActive forKey: @"active"];
|
|
|
|
[calendar setObject: owner forKey: @"owner"];
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: [folder isWebCalendar]] forKey: @"isWebCalendar"];
|
|
|
|
if (fActiveTasks > 0)
|
|
|
|
[calendar setObject: fActiveTasks forKey:@"activeTasks" ];
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: [folder includeInFreeBusy]] forKey: @"includeInFreeBusy"];
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: [folder showCalendarAlarms]] forKey: @"showCalendarAlarms"];
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: [folder showCalendarTasks]] forKey: @"showCalendarTasks"];
|
|
|
|
|
|
|
|
// We extract ACLs for this address book
|
|
|
|
allACLs = ([owner isEqualToString: userLogin] ? nil : [folder aclsForUser: userLogin]);
|
|
|
|
objectCreator = ([owner isEqualToString: userLogin] || [allACLs containsObject: SOGoRole_ObjectCreator]);
|
|
|
|
objectEraser = ([owner isEqualToString: userLogin] || [allACLs containsObject: SOGoRole_ObjectEraser]);
|
|
|
|
acls = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: objectCreator], @"objectCreator",
|
|
|
|
[NSNumber numberWithBool: objectEraser], @"objectEraser", nil];
|
|
|
|
|
|
|
|
|
|
|
|
if ([folder isKindOfClass: [SOGoWebAppointmentFolder class]])
|
|
|
|
objectCreator = objectEraser = synchronize = NO;
|
2015-01-26 21:36:55 +01:00
|
|
|
else
|
2015-12-10 17:11:22 +01:00
|
|
|
synchronize = [folder synchronize];
|
|
|
|
|
|
|
|
[calendar setObject: acls forKey: @"acls"];
|
|
|
|
|
|
|
|
if ([[folder nameInContainer] isEqualToString: @"personal"])
|
|
|
|
synchronize = YES;
|
|
|
|
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: synchronize] forKey: @"synchronize"];
|
|
|
|
|
|
|
|
if ([folder isWebCalendar])
|
2015-01-26 21:36:55 +01:00
|
|
|
{
|
2015-12-10 17:11:22 +01:00
|
|
|
urls = [NSMutableDictionary dictionaryWithObject: [folder folderPropertyValueInCategory: @"WebCalendars"]
|
|
|
|
forKey: @"webCalendarURL"];
|
|
|
|
if ([folder respondsToSelector: @selector (reloadOnLogin)])
|
|
|
|
reloadOnLogin = [(SOGoWebAppointmentFolder *) folder reloadOnLogin];
|
|
|
|
else
|
|
|
|
reloadOnLogin = NO;
|
|
|
|
[calendar setObject: [NSNumber numberWithBool: reloadOnLogin] forKey: @"reloadOnLogin"];
|
2015-01-26 21:36:55 +01:00
|
|
|
}
|
2015-12-10 17:11:22 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
urls = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
[folder calDavURL], @"calDavURL",
|
|
|
|
[folder webDavICSURL], @"webDavICSURL",
|
|
|
|
[folder webDavXMLURL], @"webDavXMLURL",
|
|
|
|
nil];
|
|
|
|
if ([self isPublicAccessEnabled])
|
|
|
|
{
|
|
|
|
[urls setObject: [folder publicCalDavURL] forKey: @"publicCalDavURL"];
|
|
|
|
[urls setObject: [folder publicWebDavICSURL] forKey: @"publicWebDavICSURL"];
|
|
|
|
[urls setObject: [folder publicWebDavXMLURL] forKey: @"publicWebDavXMLURL"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[calendar setObject: urls forKey: @"urls"];
|
2015-01-26 21:36:55 +01:00
|
|
|
|
2015-12-10 17:11:22 +01:00
|
|
|
if ([userLogin isEqualToString: [folder ownerInContext: context]])
|
|
|
|
{
|
|
|
|
notifications = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
[NSNumber numberWithBool: [folder notifyOnPersonalModifications]],
|
|
|
|
@"notifyOnPersonalModifications",
|
|
|
|
[NSNumber numberWithBool: [folder notifyOnExternalModifications]],
|
|
|
|
@"notifyOnExternalModifications",
|
|
|
|
[NSNumber numberWithBool: [folder notifyUserOnPersonalModifications]],
|
|
|
|
@"notifyUserOnPersonalModifications",
|
|
|
|
nil];
|
|
|
|
if ([folder notifiedUserOnPersonalModifications])
|
|
|
|
[calendar setObject: [folder notifiedUserOnPersonalModifications] forKey: @"notifiedUserOnPersonalModifications"];
|
|
|
|
[calendar setObject: notifications forKey: @"notifications"];
|
|
|
|
}
|
2015-01-26 21:36:55 +01:00
|
|
|
|
2015-12-10 17:11:22 +01:00
|
|
|
[calendars addObject: calendar];
|
|
|
|
}
|
2016-04-27 21:25:01 +02:00
|
|
|
}
|
2015-12-10 17:11:22 +01:00
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
return calendars;
|
2007-03-29 20:08:40 +02:00
|
|
|
}
|
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
- (void) setCurrentCalendar: (NSDictionary *) newCalendar
|
2007-03-29 20:08:40 +02:00
|
|
|
{
|
2007-09-15 00:01:02 +02:00
|
|
|
ASSIGN (currentCalendar, newCalendar);
|
2007-03-29 20:08:40 +02:00
|
|
|
}
|
|
|
|
|
2007-09-15 00:01:02 +02:00
|
|
|
- (NSDictionary *) currentCalendar
|
2007-03-29 20:08:40 +02:00
|
|
|
{
|
2007-09-15 00:01:02 +02:00
|
|
|
return currentCalendar;
|
2007-03-29 20:08:40 +02:00
|
|
|
}
|
|
|
|
|
2007-10-24 17:52:08 +02:00
|
|
|
- (NSString *) currentCalendarClass
|
|
|
|
{
|
|
|
|
return [currentCalendar
|
|
|
|
keysWithFormat: @"colorBox calendarFolder%{folder}"];
|
|
|
|
}
|
|
|
|
|
2007-03-29 20:08:40 +02:00
|
|
|
- (NSString *) currentCalendarStyle
|
|
|
|
{
|
2007-09-15 00:01:02 +02:00
|
|
|
return [currentCalendar
|
|
|
|
keysWithFormat: @"color: %{color}; background-color: %{color};"];
|
2007-03-29 20:08:40 +02:00
|
|
|
}
|
|
|
|
|
2008-04-22 19:16:37 +02:00
|
|
|
/* code taken from Lightning 0.7 */
|
|
|
|
- (NSString *) contrastingTextColor
|
|
|
|
{
|
|
|
|
NSString *bgColor;
|
|
|
|
unsigned int red, green, blue;
|
|
|
|
float brightness;
|
|
|
|
|
|
|
|
bgColor = [[currentCalendar objectForKey: @"color"] substringFromIndex: 1];
|
|
|
|
red = _intValueFromHex ([bgColor substringFromRange: NSMakeRange (0, 2)]);
|
|
|
|
green = _intValueFromHex ([bgColor substringFromRange: NSMakeRange (2, 2)]);
|
|
|
|
blue = _intValueFromHex ([bgColor substringFromRange: NSMakeRange (4, 2)]);
|
|
|
|
brightness = (0.299 * red) + (0.587 * green) + (0.114 * blue);
|
|
|
|
|
|
|
|
return ((brightness < 144) ? @"white" : @"black");
|
|
|
|
}
|
|
|
|
|
2015-01-22 18:12:51 +01:00
|
|
|
/**
|
|
|
|
* @api {get} /so/:username/Calendar/:calendarId/calendarslist Get calendars
|
|
|
|
* @apiVersion 1.0.0
|
|
|
|
* @apiName GetCalendarsList
|
|
|
|
* @apiGroup Calendar
|
|
|
|
* @apiExample {curl} Example usage:
|
|
|
|
* curl -i http://localhost/SOGo/so/sogo1/Calendar/calendarslist
|
|
|
|
*
|
2015-01-26 21:36:55 +01:00
|
|
|
* @apiSuccess (Success 200) {Object[]} calendars List of calendars
|
|
|
|
* @apiSuccess (Success 200) {String} calendars.id Calendar ID
|
2015-03-30 20:03:28 +02:00
|
|
|
* @apiSuccess (Success 200) {String} calendars.name Human readable name
|
2015-01-26 21:36:55 +01:00
|
|
|
* @apiSuccess (Success 200) {String} calendars.owner User ID of owner
|
|
|
|
* @apiSuccess (Success 200) {String} calendars.color Calendar's hex color code
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.active 1 if the calendar is enabled
|
|
|
|
* @apiSuccess (Success 200) {Number} [calendars.activeTasks] Number of incompleted tasks
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.includeInFreeBusy 1 if calendar must be include in freebusy
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.showCalendarAlarms 1 if alarms must be enabled
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.showCalendarTasks 1 if tasks must be enabled
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.isWebCalendar 1 if calendar is a read-only external WebDAV calendar
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.reloadOnLogin 1 if calendar is a Web calendar that must be reload when user logins
|
|
|
|
* @apiSuccess (Success 200) {Object} [calendars.notifications] Notification (if active user is the calendar's owner)
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.notifications.notifyOnPersonalModifications 1 if a mail is sent for each modification made by the owner
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.notifications.notifyOnExternalModifications 1 if a mail is sent for each modification made by someone else
|
|
|
|
* @apiSuccess (Success 200) {Number} calendars.notifications.notifyUserOnPersonalModifications 1 if a mail is sent to an external address for modification made by the owner
|
|
|
|
* @apiSuccess (Success 200) {String} [calendars.notifications.notifiedUserOnPersonalModifications] Email address to notify changes
|
2015-06-15 15:19:21 +02:00
|
|
|
* @apiSuccess (Success 200) {Object[]} urls URLs to this calendar
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.calDavURL] CalDAV URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.webDavXMLURL] WebDAV XML URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.webDavICSURL] WebDAV ICS URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.publicWebDavXMLURL] Public WebDAV XML URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.publicWebDavICSURL Public WebDAV ICS URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.publicCalDavURL] Public CalDAV URL
|
|
|
|
* @apiSuccess (Success 200) {String} [urls.webCalendarURL] External WebDAV ICS URL
|
2015-01-22 18:12:51 +01:00
|
|
|
*/
|
2008-01-15 22:45:48 +01:00
|
|
|
- (WOResponse *) calendarsListAction
|
|
|
|
{
|
2015-01-22 18:12:51 +01:00
|
|
|
NSDictionary *data;
|
2008-01-15 22:45:48 +01:00
|
|
|
WOResponse *response;
|
|
|
|
|
2015-01-22 18:12:51 +01:00
|
|
|
data = [NSDictionary dictionaryWithObject: [self calendars]
|
|
|
|
forKey: @"calendars"];
|
|
|
|
response = [self responseWithStatus: 200 andJSONRepresentation: data];
|
2008-01-15 22:45:48 +01:00
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2007-03-29 20:08:40 +02:00
|
|
|
@end /* UIxCalendarSelector */
|