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.sogo
maint-2.0.2
C Robert 2009-09-10 17:26:57 +00:00
parent cec888b0c0
commit 9d46c890d1
30 changed files with 579 additions and 36 deletions

View File

@ -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):

View File

@ -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

View File

@ -125,6 +125,7 @@
- (NSException *) writeContent: (NSString *) _content
toName: (NSString *) _name;
- (NSException *) deleteContentWithName: (NSString *) _name;
- (NSException *) deleteAllContent;
- (NSException *) deleteFolder;

View File

@ -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;

View File

@ -24,6 +24,7 @@ Appointments_OBJC_FILES = \
SOGoAppointmentOccurence.m \
SOGoTaskOccurence.m \
SOGoAppointmentFolder.m \
SOGoWebAppointmentFolder.m \
SOGoAppointmentFolders.m \
SOGoFreeBusyObject.m \
SOGoUserFolder+Appointments.m \

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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__ */

View File

@ -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 */

View File

@ -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 = {

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -31,6 +31,7 @@ SchedulerUI_OBJC_FILES = \
UIxAptTableView.m \
\
UIxCalListingActions.m \
UIxCalMainActions.m \
\
UIxAttendeesEditor.m \
UIxComponentEditor.m \

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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]

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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";

View File

@ -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";

View File

@ -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..."

View File

@ -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");