Added support for remote iCal calendars.
Monotone-Parent: a1fe20acf2d2d8408bcf2e8c36a38204f8d1bfad Monotone-Revision: bb2513b08d345dfc89b0cd702a39ac0eeb276c3d Monotone-Author: crobert@inverse.ca Monotone-Date: 2009-09-10T17:26:57 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
cec888b0c0
commit
9d46c890d1
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2009-09-10 Cyril Robert <crobert@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoWebAppointmentFolder.m: New
|
||||
SOGoAppointmentFolder subclass to manage iCal subscriptions.
|
||||
* UI/Scheduler/UIxCalMainActions.m: New action class to handle actions on
|
||||
the main calendar.
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m (importCalendar:): New
|
||||
method to import everything from an iCalCalendar. (Refactoring from
|
||||
UIxCalFolderActions)
|
||||
* SoObjects/Appointments/SOGoAppointmentFolders.m (webCalendarIds): New
|
||||
method to get uids of web calendar folders.
|
||||
(_fetchPersonalFolders: withChannel:): Wrap the parent method to replace web
|
||||
calendar folders with the correct class: SOGoWebAppointmentFolder. It also
|
||||
removes invalid references in the WebCalendars setting.
|
||||
* UI/Scheduler/UIxCalFolderActions.m (importAction): Moved a big part of the
|
||||
method to [SOGoAppointmentFolder importCalendar:].
|
||||
* SoObjects/Appointments/SOGoWebAppointmentFolder.m (delete): Wrap the
|
||||
parent method to remove the calendar for the user's settings.
|
||||
|
||||
2009-09-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/Scheduler/UIxComponentEditor.m (-setComment,comment):
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-09-10 Cyril Robert <crobert@inverse.ca>
|
||||
|
||||
* GCSFolder.m (deleteAllContent): New method to delete everything in the
|
||||
folder (use with caution).
|
||||
|
||||
2009-08-14 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* GCSFolder.m (-deleteAclWithSpecification:): enable the deletion
|
||||
|
|
|
@ -125,6 +125,7 @@
|
|||
- (NSException *) writeContent: (NSString *) _content
|
||||
toName: (NSString *) _name;
|
||||
- (NSException *) deleteContentWithName: (NSString *) _name;
|
||||
- (NSException *) deleteAllContent;
|
||||
|
||||
- (NSException *) deleteFolder;
|
||||
|
||||
|
|
|
@ -1092,6 +1092,57 @@ static NSArray *contentFieldNames = nil;
|
|||
return error;
|
||||
}
|
||||
|
||||
- (NSException *) deleteAllContent {
|
||||
NSException *error = nil;
|
||||
NSString *query;
|
||||
EOAdaptorChannel *storeChannel, *quickChannel;
|
||||
|
||||
if ((storeChannel = [self acquireStoreChannel]) == nil) {
|
||||
[self errorWithFormat:@"could not open storage channel!"];
|
||||
return nil;
|
||||
}
|
||||
if (ofFlags.sameTableForQuick)
|
||||
quickChannel = nil;
|
||||
else
|
||||
{
|
||||
quickChannel = [self acquireQuickChannel];
|
||||
if (!quickChannel)
|
||||
{
|
||||
[self errorWithFormat:@"could not open quick channel!"];
|
||||
[self releaseChannel:storeChannel];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ofFlags.sameTableForQuick) [[quickChannel adaptorContext] beginTransaction];
|
||||
[[storeChannel adaptorContext] beginTransaction];
|
||||
|
||||
query = [NSString stringWithFormat: @"DELETE FROM %@", [self storeTableName]];
|
||||
error = [storeChannel evaluateExpressionX:query];
|
||||
if (error)
|
||||
[self errorWithFormat: @"%s: cannot delete content '%@': %@",
|
||||
__PRETTY_FUNCTION__, query, error];
|
||||
else if (!ofFlags.sameTableForQuick) {
|
||||
/* content row deleted, now delete the quick row */
|
||||
query = [NSString stringWithFormat: @"DELETE FROM %@", [self quickTableName]];
|
||||
error = [quickChannel evaluateExpressionX: query];
|
||||
if (error)
|
||||
[self errorWithFormat: @"%s: cannot delete quick row '%@': %@",
|
||||
__PRETTY_FUNCTION__, query, error];
|
||||
}
|
||||
|
||||
/* release channels and return */
|
||||
[[storeChannel adaptorContext] commitTransaction];
|
||||
[self releaseChannel:storeChannel];
|
||||
|
||||
if (!ofFlags.sameTableForQuick) {
|
||||
[[quickChannel adaptorContext] commitTransaction];
|
||||
[self releaseChannel:quickChannel];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
- (NSException *)deleteFolder {
|
||||
EOAdaptorChannel *channel;
|
||||
NSString *delsql;
|
||||
|
|
|
@ -24,6 +24,7 @@ Appointments_OBJC_FILES = \
|
|||
SOGoAppointmentOccurence.m \
|
||||
SOGoTaskOccurence.m \
|
||||
SOGoAppointmentFolder.m \
|
||||
SOGoWebAppointmentFolder.m \
|
||||
SOGoAppointmentFolders.m \
|
||||
SOGoFreeBusyObject.m \
|
||||
SOGoUserFolder+Appointments.m \
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
@class NSString;
|
||||
@class NSTimeZone;
|
||||
@class GCSFolder;
|
||||
@class iCalCalendar;
|
||||
|
||||
@interface SOGoAppointmentFolder : SOGoGCSFolder
|
||||
{
|
||||
|
@ -145,6 +146,7 @@
|
|||
withWriteAccess: (BOOL) hasWriteAccess;
|
||||
|
||||
- (BOOL) importComponent: (iCalEntityObject *) event;
|
||||
- (int) importCalendar: (iCalCalendar *) calendar;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -3196,4 +3196,41 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
return ([object saveContentString: content] == nil);
|
||||
}
|
||||
|
||||
- (int) importCalendar: (iCalCalendar *) calendar
|
||||
{
|
||||
NSArray *components;
|
||||
int imported, count, i;
|
||||
|
||||
imported = 0;
|
||||
|
||||
if (calendar)
|
||||
{
|
||||
components = [calendar events];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([self importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
|
||||
components = [calendar todos];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([self importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
|
||||
components = [calendar journals];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([self importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
|
||||
components = [calendar freeBusys];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([self importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
}
|
||||
|
||||
return imported;
|
||||
}
|
||||
|
||||
@end /* SOGoAppointmentFolder */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WORequest+So.h>
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
|
@ -37,6 +38,7 @@
|
|||
#import <SOGo/SOGoWebDAVValue.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import "SOGoAppointmentFolder.h"
|
||||
#import "SOGoWebAppointmentFolder.h"
|
||||
|
||||
#import "SOGoAppointmentFolders.h"
|
||||
|
||||
|
@ -269,4 +271,64 @@
|
|||
return proxyFolders;
|
||||
}
|
||||
|
||||
- (NSArray *) webCalendarIds
|
||||
{
|
||||
NSUserDefaults *us;
|
||||
NSDictionary *tmp, *calendars;
|
||||
NSArray *rc;
|
||||
|
||||
rc = nil;
|
||||
|
||||
us = [[context activeUser] userSettings];
|
||||
tmp = [us objectForKey: @"Calendar"];
|
||||
if (tmp)
|
||||
{
|
||||
calendars = [tmp objectForKey: @"WebCalendars"];
|
||||
if (calendars)
|
||||
rc = [calendars allKeys];
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
rc = [NSArray array];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSException *) _fetchPersonalFolders: (NSString *) sql
|
||||
withChannel: (EOAdaptorChannel *) fc
|
||||
{
|
||||
int count, max;
|
||||
NSArray *webCalendarIds;
|
||||
NSString *name;
|
||||
SOGoAppointmentFolder *old;
|
||||
SOGoWebAppointmentFolder *folder;
|
||||
NSException *error;
|
||||
BOOL isWebRequest;
|
||||
|
||||
isWebRequest = [[context request] handledByDefaultHandler];
|
||||
error = [super _fetchPersonalFolders: sql withChannel: fc];
|
||||
|
||||
webCalendarIds = [self webCalendarIds];
|
||||
max = [webCalendarIds count];
|
||||
if (!error && max)
|
||||
{
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
name = [webCalendarIds objectAtIndex: count];
|
||||
if (isWebRequest)
|
||||
{
|
||||
old = [subFolders objectForKey: name];
|
||||
folder = [SOGoWebAppointmentFolder objectWithName: name
|
||||
inContainer: self];
|
||||
[folder setOCSPath: [old ocsPath]];
|
||||
[subFolders setObject: folder forKey: name];
|
||||
}
|
||||
else
|
||||
[subFolders removeObjectForKey: name];
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* SOGoWebAppointmentFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Cyril Robert <crobert@inverse.ca>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __Appointments_SOGoWebAppointmentFolder_H__
|
||||
#define __Appointments_SOGoWebAppointmentFolder_H__
|
||||
|
||||
#import "SOGoAppointmentFolder.h"
|
||||
|
||||
@interface SOGoWebAppointmentFolder : SOGoAppointmentFolder
|
||||
|
||||
- (int) loadWebCalendar: (NSString *) location;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __Appointments_SOGoWebAppointmentFolder_H__ */
|
|
@ -0,0 +1,84 @@
|
|||
/* SOGoWebAppointmentFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Cyril Robert <crobert@inverse.ca>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
|
||||
#import "SOGoWebAppointmentFolder.h"
|
||||
|
||||
|
||||
@implementation SOGoWebAppointmentFolder
|
||||
|
||||
- (int) loadWebCalendar: (NSString *) location
|
||||
{
|
||||
NSURL *url;
|
||||
NSData *data;
|
||||
NSString *contents;
|
||||
iCalCalendar *calendar;
|
||||
int imported = 0;
|
||||
|
||||
url = [NSURL URLWithString: location];
|
||||
|
||||
if (url)
|
||||
{
|
||||
data = [NSData dataWithContentsOfURL: url];
|
||||
contents = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[contents autorelease];
|
||||
calendar = [iCalCalendar parseSingleFromSource: contents];
|
||||
if (calendar)
|
||||
{
|
||||
[[self ocsFolder] deleteAllContent];
|
||||
imported = [self importCalendar: calendar];
|
||||
}
|
||||
}
|
||||
|
||||
return imported;
|
||||
}
|
||||
|
||||
|
||||
- (NSException *) delete
|
||||
{
|
||||
NSException *error;
|
||||
NSUserDefaults *settings;
|
||||
NSMutableDictionary *calSettings, *webCalendars;
|
||||
NSString *name;
|
||||
|
||||
settings = [[context activeUser] userSettings];
|
||||
calSettings = [settings objectForKey: @"Calendar"];
|
||||
webCalendars = [calSettings objectForKey: @"WebCalendars"];
|
||||
name = [self nameInContainer];
|
||||
|
||||
error = [super delete];
|
||||
if (!error)
|
||||
{
|
||||
[webCalendars removeObjectForKey: name];
|
||||
[settings synchronize];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@end /* SOGoAppointmentFolder */
|
|
@ -11,6 +11,24 @@
|
|||
SOGoAppointmentFolders = {
|
||||
superclass = "SOGoParentFolder";
|
||||
};
|
||||
SOGoWebAppointmentFolder = {
|
||||
superclass = "SOGoGCSFolder";
|
||||
defaultRoles = {
|
||||
"Access Contents Information" = ( "Owner", "PublicResponder", "PublicModifier", "PublicViewer", "PublicDAndTViewer", "PrivateResponder", "PrivateModifier", "PrivateViewer", "PrivateDAndTViewer", "ConfidentialResponder", "ConfidentialModifier", "ConfidentialViewer", "ConfidentialDAndTViewer" );
|
||||
"ViewWholePublicRecords" = ( "Owner", "PublicResponder", "PublicModifier", "PublicViewer" );
|
||||
"ViewWholePrivateRecords" = ( "Owner", "PrivateResponder", "PrivateModifier", "PrivateViewer" );
|
||||
"ViewWholeConfidentialRecords" = ( "Owner", "ConfidentialResponder", "ConfidentialModifier", "ConfidentialViewer" );
|
||||
"ViewDAndTOfPublicRecords" = ( "Owner", "PublicDAndTViewer" );
|
||||
"ViewDAndTOfPrivateRecords" = ( "Owner", "PrivateDAndTViewer" );
|
||||
"ViewDAndTOfConfidentialRecords" = ( "Owner", "ConfidentialDAndTViewer" );
|
||||
"ModifyPublicRecords" = ( );
|
||||
"ModifyPrivateRecords" = ( );
|
||||
"ModifyConfidentialRecords" = ( );
|
||||
"RespondToPublicRecords" = ( );
|
||||
"RespondToPrivateRecords" = ( );
|
||||
"RespondToConfidentialRecords" = ( );
|
||||
};
|
||||
};
|
||||
SOGoAppointmentFolder = {
|
||||
superclass = "SOGoGCSFolder";
|
||||
defaultRoles = {
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Tarefa Confidencial)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Důvěrný úkol)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Vertrouwelijke taak)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Confidential task)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Tâche confidentielle)";
|
|||
"Open Task..." = "Ouvrir la tâche...";
|
||||
"Mark Completed" = "Marquer comme accomplie";
|
||||
"Delete Task" = "Supprimer la tâche";
|
||||
|
||||
"Subscribe to a web calendar..." = "S'inscrire à un agenda en ligne...";
|
||||
"URL of the Calendar" = "URL de l'agenda";
|
||||
|
|
|
@ -31,6 +31,7 @@ SchedulerUI_OBJC_FILES = \
|
|||
UIxAptTableView.m \
|
||||
\
|
||||
UIxCalListingActions.m \
|
||||
UIxCalMainActions.m \
|
||||
\
|
||||
UIxAttendeesEditor.m \
|
||||
UIxComponentEditor.m \
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Vertrauliche Aufgabe)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Bizalmas feladat)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Attività confidenziale)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Confidential task)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Tarea confidencial)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSString+Utilities.h>
|
||||
|
||||
|
@ -98,13 +97,12 @@
|
|||
{
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSMutableDictionary *rc;
|
||||
NSArray *components;
|
||||
WORequest *request;
|
||||
WOResponse *response;
|
||||
NSString *fileContent;
|
||||
id data;
|
||||
iCalCalendar *additions;
|
||||
int i, count, imported;
|
||||
int imported;
|
||||
|
||||
imported = 0;
|
||||
rc = [NSMutableDictionary dictionary];
|
||||
|
@ -124,29 +122,7 @@
|
|||
&& [fileContent hasPrefix: @"BEGIN:"])
|
||||
{
|
||||
additions = [iCalCalendar parseSingleFromSource: fileContent];
|
||||
if (additions)
|
||||
{
|
||||
components = [additions events];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([folder importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
components = [additions todos];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([folder importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
components = [additions journals];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([folder importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
components = [additions freeBusys];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
if ([folder importComponent: [components objectAtIndex: i]])
|
||||
imported++;
|
||||
}
|
||||
imported = [folder importCalendar: additions];
|
||||
}
|
||||
|
||||
[rc setObject: [NSNumber numberWithInt: imported]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* UIxCalMainActions.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Cyril Robert <crobert@inverse.ca>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef UIXCALMAINACTIONS_H
|
||||
#define UIXCALMAINACTIONS_H
|
||||
|
||||
#import <Common/WODirectAction+SOGo.h>
|
||||
|
||||
@interface UIxCalMainActions : WODirectAction
|
||||
|
||||
- (void) saveUrl: (NSURL *) calendarURL
|
||||
forCalendar: (NSString *) calendarName;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* UIXCALMAINACTIONS_H */
|
|
@ -0,0 +1,129 @@
|
|||
/* UIxCalMainActions.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Cyril Robert <crobert@inverse.ca>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
#import <SoObjects/Appointments/SOGoWebAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolders.h>
|
||||
|
||||
#import "UIxCalMainActions.h"
|
||||
|
||||
@implementation UIxCalMainActions
|
||||
|
||||
- (WOResponse *) addWebCalendarAction
|
||||
{
|
||||
WORequest *r;
|
||||
WOResponse *response;
|
||||
SOGoWebAppointmentFolder *folder;
|
||||
NSURL *url;
|
||||
NSString *name;
|
||||
NSMutableDictionary *rc;
|
||||
int imported = 0;
|
||||
|
||||
r = [context request];
|
||||
rc = [NSMutableDictionary dictionary];
|
||||
|
||||
// Just a check
|
||||
url = [NSURL URLWithString: [r formValueForKey: @"url"]];
|
||||
if (url)
|
||||
{
|
||||
[[self clientObject] newFolderWithName: @"Web Calendar"
|
||||
nameInContainer: &name];
|
||||
[self saveUrl: url forCalendar: name];
|
||||
folder = [[self clientObject] lookupName: name
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
if (folder)
|
||||
{
|
||||
imported = [folder loadWebCalendar: [r formValueForKey: @"url"]];
|
||||
[rc setObject: @"Web Calendar" forKey: @"displayname"];
|
||||
[rc setObject: name forKey: @"name"];
|
||||
[rc setObject: [NSNumber numberWithInt: imported]
|
||||
forKey: @"imported"];
|
||||
}
|
||||
}
|
||||
|
||||
response = [self responseWithStatus: 200];
|
||||
[response appendContentString: [rc jsonRepresentation]];
|
||||
return response;
|
||||
}
|
||||
|
||||
- (void) saveUrl: (NSURL *) calendarURL
|
||||
forCalendar: (NSString *) calendarName
|
||||
{
|
||||
NSUserDefaults *settings;
|
||||
NSMutableDictionary *calSettings, *webCalendars;
|
||||
|
||||
settings = [[context activeUser] userSettings];
|
||||
calSettings = [settings objectForKey: @"Calendar"];
|
||||
webCalendars = [calSettings objectForKey: @"WebCalendars"];
|
||||
if (!webCalendars)
|
||||
{
|
||||
webCalendars = [NSMutableDictionary dictionary];
|
||||
[calSettings setObject: webCalendars forKey: @"WebCalendars"];
|
||||
}
|
||||
[webCalendars setObject: calendarURL forKey: calendarName];
|
||||
[settings synchronize];
|
||||
}
|
||||
|
||||
- (WOResponse *) reloadWebCalendarsAction
|
||||
{
|
||||
NSUserDefaults *settings;
|
||||
NSMutableDictionary *calSettings, *webCalendars;
|
||||
NSArray *calendarIds;
|
||||
SOGoWebAppointmentFolder *folder;
|
||||
NSString *name, *url;
|
||||
int i, count, imported;
|
||||
|
||||
settings = [[context activeUser] userSettings];
|
||||
calSettings = [settings objectForKey: @"Calendar"];
|
||||
webCalendars = [calSettings objectForKey: @"WebCalendars"];
|
||||
|
||||
if (webCalendars)
|
||||
{
|
||||
calendarIds = [webCalendars allKeys];
|
||||
count = [calendarIds count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
name = [calendarIds objectAtIndex: i];
|
||||
url = [webCalendars objectForKey: name];
|
||||
folder = [[self clientObject] lookupName: name
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
if (folder)
|
||||
imported = [folder loadWebCalendar: url];
|
||||
}
|
||||
}
|
||||
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
|
@ -49,6 +49,7 @@
|
|||
#import <SoObjects/Appointments/iCalEntityObject+SOGo.h>
|
||||
#import <SoObjects/Appointments/iCalPerson+SOGo.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoWebAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolders.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentOccurence.h>
|
||||
|
@ -2045,18 +2046,23 @@ RANGE(2);
|
|||
{
|
||||
SOGoContentObject <SOGoComponentOccurence> *clientObject;
|
||||
SOGoUser *ownerUser;
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
ownerUser = [SOGoUser userWithLogin: [clientObject ownerInContext: context]
|
||||
roles: nil];
|
||||
|
||||
if ([ownerUser isEqual: [context activeUser]])
|
||||
rc = [self ownerIsAttendee: ownerUser
|
||||
andClientObject: clientObject];
|
||||
if ([componentCalendar isKindOfClass: [SOGoWebAppointmentFolder class]])
|
||||
rc = 1;
|
||||
else
|
||||
rc = [self delegateIsAttendee: ownerUser
|
||||
andClientObject: clientObject];
|
||||
{
|
||||
if ([ownerUser isEqual: [context activeUser]])
|
||||
rc = [self ownerIsAttendee: ownerUser
|
||||
andClientObject: clientObject];
|
||||
else
|
||||
rc = [self delegateIsAttendee: ownerUser
|
||||
andClientObject: clientObject];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -533,3 +533,6 @@ vtodo_class2 = "(Tasg gyhoeddus)";
|
|||
"Open Task..." = "Open Task...";
|
||||
"Mark Completed" = "Mark Completed";
|
||||
"Delete Task" = "Delete Task";
|
||||
|
||||
"Subscribe to a web calendar..." = "Subscribe to a web calendar...";
|
||||
"URL of the Calendar" = "URL of the Calendar";
|
||||
|
|
|
@ -40,6 +40,16 @@
|
|||
protectedBy = "View";
|
||||
pageName = "UIxCalMainView";
|
||||
};
|
||||
addWebCalendar = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalMainActions";
|
||||
actionName = "addWebCalendar";
|
||||
};
|
||||
reloadWebCalendars = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalMainActions";
|
||||
actionName = "reloadWebCalendars";
|
||||
};
|
||||
saveDragHandleState = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxCalMainView";
|
||||
|
|
|
@ -20,6 +20,10 @@ div.colorBox.calendarFolder<var:string value="currentCalendar.folder" />
|
|||
><span class="toolbarButton"><img rsrc:src="add-calendar.png"
|
||||
label:title="New Calendar..."
|
||||
/></span></a>
|
||||
<a href="#" class="toolbarButton"
|
||||
><span class="toolbarButton"><img rsrc:src="add-web-calendar.png"
|
||||
label:title="Subscribe to a web calendar..."
|
||||
/></span></a>
|
||||
<a href="#" class="toolbarButton"
|
||||
><span class="toolbarButton"><img rsrc:src="add-user-calendar.png"
|
||||
label:title="Subscribe to a Calendar..."
|
||||
|
|
|
@ -872,11 +872,23 @@ function onMonthOverview() {
|
|||
}
|
||||
|
||||
function onCalendarReload() {
|
||||
changeCalendarDisplay(null, currentView);
|
||||
|
||||
reloadWebCalendars ();
|
||||
return false;
|
||||
}
|
||||
|
||||
function reloadWebCalendars () {
|
||||
var url = ApplicationBaseURL + "reloadWebCalendars";
|
||||
if (document.reloadWebCalAjaxRequest) {
|
||||
document.reloadWebCalAjaxRequest.aborted = true;
|
||||
document.reloadWebCalAjaxRequest.abort();
|
||||
}
|
||||
document.reloadWebCalAjaxRequest
|
||||
= triggerAjaxRequest(url, reloadWebCalendarsCallback);
|
||||
}
|
||||
function reloadWebCalendarsCallback (http) {
|
||||
changeCalendarDisplay(null, currentView);
|
||||
}
|
||||
|
||||
function scrollDayView(scrollEvent) {
|
||||
if (!preventAutoScroll) {
|
||||
if (scrollEvent) {
|
||||
|
@ -1830,8 +1842,9 @@ function initCalendarSelector() {
|
|||
|
||||
var links = $("calendarSelectorButtons").childNodesWithTag("a");
|
||||
$(links[0]).observe("click", onCalendarNew);
|
||||
$(links[1]).observe("click", onCalendarAdd);
|
||||
$(links[2]).observe("click", onCalendarRemove);
|
||||
$(links[1]).observe("click", onCalendarWebAdd);
|
||||
$(links[2]).observe("click", onCalendarAdd);
|
||||
$(links[3]).observe("click", onCalendarRemove);
|
||||
}
|
||||
|
||||
function onCalendarModify(event) {
|
||||
|
@ -1877,6 +1890,27 @@ function onCalendarAdd(event) {
|
|||
openUserFolderSelector(onFolderSubscribeCB, "calendar");
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function onCalendarWebAdd(event) {
|
||||
var calendarUrl = window.prompt(labels["URL of the Calendar"], "");
|
||||
if (calendarUrl) {
|
||||
if (document.addWebCalendarRequest) {
|
||||
document.addWebCalendarRequest.aborted = true;
|
||||
document.addWebCalendarRequest.abort ();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/addWebCalendar?url=" + escape (calendarUrl);
|
||||
document.addWebCalendarRequest =
|
||||
triggerAjaxRequest (url, addWebCalendarCallback);
|
||||
}
|
||||
}
|
||||
function addWebCalendarCallback (http) {
|
||||
var data = http.responseText.evalJSON(true);
|
||||
appendCalendar(data.displayname, "/" + data.name);
|
||||
refreshEvents();
|
||||
refreshTasks();
|
||||
changeCalendarDisplay();
|
||||
}
|
||||
|
||||
function onCalendarExport(event) {
|
||||
var node = $("calendarList").getSelectedNodes().first();
|
||||
var owner = node.getAttribute("owner");
|
||||
|
|
Loading…
Reference in New Issue