merge of '0e8b1704a04c5c494b76cbc377b9d9075df6cb1a'

and '3665058235c9d303e295671add1811764b128816'

Monotone-Parent: 0e8b1704a04c5c494b76cbc377b9d9075df6cb1a
Monotone-Parent: 3665058235c9d303e295671add1811764b128816
Monotone-Revision: 4d711e074341810486c1842c6a345777cc3664bb

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2009-09-10T18:22:56
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Francis Lachapelle
2009-09-10 18:22:56 +00:00
32 changed files with 618 additions and 39 deletions
+27
View File
@@ -1,3 +1,30 @@
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.
* SoObjects/Appointments/SOGoWebAppointmentFolder.m: Added some error
management, for when the url is invalid / not ical / etc.
2009-09-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/Scheduler/UIxComponentEditor.m (-setComment,comment):
properly substitute the form-provided "\r\n" sequences with "\n"
sequences and vice-versa.
2009-09-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentFolder.m
+5
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
+1
View File
@@ -125,6 +125,7 @@
- (NSException *) writeContent: (NSString *) _content
toName: (NSString *) _name;
- (NSException *) deleteContentWithName: (NSString *) _name;
- (NSException *) deleteAllContent;
- (NSException *) deleteFolder;
+51
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;
+1
View File
@@ -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,88 @@
/* 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];
}
else
{
imported = -1;
}
}
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 */
+18
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 = {
@@ -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";
+1
View File
@@ -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";
+2 -26
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]
+35
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 */
+137
View File
@@ -0,0 +1,137 @@
/* 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"]];
if (imported >= 0)
{
[rc setObject: @"Web Calendar" forKey: @"displayname"];
[rc setObject: name forKey: @"name"];
}
else
{
[folder delete];
}
[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
+15 -8
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>
@@ -806,12 +807,13 @@ iRANGE(2);
- (void) setComment: (NSString *) _value
{
ASSIGN (comment, _value);
#warning should we do the same for "location" and "summary"? What about ContactsUI?
ASSIGN (comment, [_value stringByReplacingString: @"\r\n" withString: @"\n"]);
}
- (NSString *) comment
{
return comment;
return [comment stringByReplacingString: @"\n" withString: @"\r\n"];
}
- (BOOL) hasComment
@@ -2044,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";
+10
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";
@@ -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..."
+43 -4
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,32 @@ 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);
if (data.imported > 0) {
appendCalendar(data.displayname, "/" + data.name);
refreshEvents();
refreshTasks();
changeCalendarDisplay();
}
else {
alert (labels["An error occured while importing calendar."]);
}
}
function onCalendarExport(event) {
var node = $("calendarList").getSelectedNodes().first();
var owner = node.getAttribute("owner");
+9
View File
@@ -56,6 +56,15 @@ function initPreferences() {
resetTableActions ();
$("categoryAdd").observe ("click", onCategoryAdd);
$("categoryDelete").observe ("click", onCategoryDelete);
// Disable placement (after) if composing in HTML
if ($("composeMessagesType")) {
if ($("composeMessagesType").value == 1) {
$("replyPlacementList").selectedIndex = 0;
$("replyPlacementList").disabled = 1;
onReplyPlacementListChange ();
}
}
}
function resetTableActions() {
+2 -1
View File
@@ -1,8 +1,9 @@
sogo (X) unstable; urgency=low
* Install a default Apache 2 configuration file.
* Added a dependency on sope4.9-libxmlsaxdriver.
-- Inverse Support <support@inverse.ca> Wed, 19 Aug 2009 09:42:15 -0400
-- Inverse Support <support@inverse.ca> Wed, 10 Sept 2009 09:42:15 -0400
sogo (1.0.4) unstable; urgency=low