see changelog

Monotone-Parent: 399ddcc3b0b509af5a4d05cd434475774187e48c
Monotone-Revision: 0cee430f2a0dfc64e4d3616db2934929c59abbbf

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2007-12-03T14:13:10
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Ludovic Marcotte 2007-12-03 14:13:10 +00:00
parent 1bbd867cbe
commit 296245f3c1
29 changed files with 888 additions and 24 deletions

View File

@ -1,3 +1,33 @@
2007-12-03 Ludovic Marcotte <ludovic@inverse.ca>
* Main/NSException+Stacktrace.{h,m} - new files
to handle automatic stack trace generation
upon an uncaught exception.
* Updated the templates and Localizable.string files
to fix typos and add new strings.
* SoObjects/Mailer/SOGoMailBodyPart.m
Fixed attachment retreival when the first character
is a digit.
* SoObjects/SOGo/SOGoGCSFolder.m
Fixed the sending of emails when folders are created/removed.
Notifications are sent if the defaults SOGoFoldersSendEMailNotifications
is set to YES.
* UI/Common/UIxUserRightsEditor.m
* UI/Templates/SOGoACLEnglishModificationAdvisory.wox
* UI/Templates/SOGoACLFrenchModificationAdvisory.wox
* UI/Templates/SOGoACLGermanModificationAdvisory.wox
Added the capabilities to email notifications when ACLs have
changed on a DAV collection or an IMAP mailbox. Also added
new templates (3 .wox) to deal with this.
* UI/WebServerResources/ContactsUI.js
UI/WebServerResources/SchedulerUI.js
Added warnings on operations w/o selection.
2007-11-30 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/SOGoParentFolder.m ([SOGoParentFolder

View File

@ -17,6 +17,7 @@ all::
$(SOGOD)_OBJC_FILES += \
sogod.m \
NSException+Stacktrace.m\
SOGo.m \
SOGoProductLoader.m \
build.m

View File

@ -0,0 +1,37 @@
/** Interface for NSException for GNUStep
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: Adam Fedor <fedor@boulder.colorado.edu>
Date: 1995
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
<title>NSException and NSAssertionHandler class reference</title>
AutogsdocSource: NSAssertionHandler.m
AutogsdocSource: NSException.m
*/
#import <Foundation/NSException.h>
@interface NSException (SOGoExtensions)
- (void) raise;
@end

View File

@ -0,0 +1,540 @@
/** NSException - Object encapsulation of a general exception handler
Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
Written by: Adam Fedor <fedor@boulder.colorado.edu>
Date: Mar 1995
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
$Date: 2007-09-14 07:36:11 -0400 (Fri, 14 Sep 2007) $ $Revision: 25482 $
NOTE: This code was taken from GNUstep Base Library and sligthly modified
by Ludovic Marcotte <ludovic@inverse.ca>
*/
#include "NSException+Stacktrace.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSBundle.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSNull.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSThread.h>
//
//
//
static void _terminate()
{
abort();
}
static void
_NSFoundationUncaughtExceptionHandler (NSException *exception)
{
NSString *stack;
fprintf(stderr, "Uncaught exception %s, reason: %s\n",
[[exception name] lossyCString], [[exception reason] lossyCString]);
fflush(stderr); /* NEEDED UNDER MINGW */
stack = [[[exception userInfo] objectForKey: @"GSStackTraceKey"] description];
if (stack != nil)
{
fprintf(stderr, "Stack\n%s\n", [stack lossyCString]);
}
fflush(stderr); /* NEEDED UNDER MINGW */
_terminate();
}
//
//
//
#define STACKSYMBOLS 1
@interface GSStackTrace : NSObject
{
NSMutableArray *frames;
}
+ (GSStackTrace*) currentStack;
- (NSString*) description;
- (NSEnumerator*) enumerator;
- (id) frameAt: (unsigned)index;
- (unsigned) frameCount;
- (NSEnumerator*) reverseEnumerator;
@end
#if defined(STACKSYMBOLS)
// GSStackTrace inspired by FYStackTrace.m
// created by Wim Oudshoorn on Mon 11-Apr-2006
// reworked by Lloyd Dupont @ NovaMind.com on 4-May-2006
#include <bfd.h>
@class GSBinaryFileInfo;
@interface GSFunctionInfo : NSObject
{
void *_address;
NSString *_fileName;
NSString *_functionName;
int _lineNo;
GSBinaryFileInfo *_module;
}
- (void*) address;
- (NSString *) fileName;
- (NSString *) function;
- (id) initWithModule: (GSBinaryFileInfo*)module
address: (void*)address
file: (NSString*)file
function: (NSString*)function
line: (int)lineNo;
- (int) lineNumber;
- (GSBinaryFileInfo*) module;
@end
@interface GSBinaryFileInfo : NSObject
{
NSString *_fileName;
bfd *_abfd;
asymbol **_symbols;
long _symbolCount;
}
- (NSString *) fileName;
- (GSFunctionInfo *) functionForAddress: (void*) address;
- (id) initWithBinaryFile: (NSString *)fileName;
- (id) init; // return info for the current executing process
@end
@implementation GSFunctionInfo
- (void*) address
{
return _address;
}
- (oneway void) dealloc
{
[_module release];
_module = nil;
[_fileName release];
_fileName = nil;
[_functionName release];
_functionName = nil;
[super dealloc];
}
- (NSString *) description
{
return [NSString stringWithFormat: @"(%@: %p) %@ %@: %d",
[_module fileName], _address, _functionName, _fileName, _lineNo];
}
- (NSString *) fileName
{
return _fileName;
}
- (NSString *) function
{
return _functionName;
}
- (id) init
{
[self release];
return nil;
}
- (id) initWithModule: (GSBinaryFileInfo*)module
address: (void*)address
file: (NSString*)file
function: (NSString*)function
line: (int)lineNo
{
_module = [module retain];
_address = address;
_fileName = [file retain];
_functionName = [function retain];
_lineNo = lineNo;
return self;
}
- (int) lineNumber
{
return _lineNo;
}
- (GSBinaryFileInfo *) module
{
return _module;
}
@end
@implementation GSBinaryFileInfo
+ (GSBinaryFileInfo*) infoWithBinaryFile: (NSString *)fileName
{
return [[[self alloc] initWithBinaryFile: fileName] autorelease];
}
+ (void) initialize
{
static BOOL first = YES;
if (first == NO)
{
return;
}
first = NO;
bfd_init ();
}
- (oneway void) dealloc
{
[_fileName release];
_fileName = nil;
if (_abfd)
{
bfd_close (_abfd);
_abfd = NULL;
}
if (_symbols)
{
objc_free (_symbols);
_symbols = NULL;
}
[super dealloc];
}
- (NSString *) fileName
{
return _fileName;
}
- (id) init
{
NSString *processName;
processName = [[[NSProcessInfo processInfo] arguments] objectAtIndex: 0];
return [self initWithBinaryFile: processName];
}
- (id) initWithBinaryFile: (NSString *)fileName
{
int neededSpace;
// 1st initialize the bfd
if ([fileName length] == 0)
{
//NSLog (@"GSBinaryFileInfo: No File");
[self release];
return nil;
}
_fileName = [fileName copy];
_abfd = bfd_openr ([fileName cString], NULL);
if (!_abfd)
{
//NSLog (@"GSBinaryFileInfo: No Binary Info");
[self release];
return nil;
}
if (!bfd_check_format_matches (_abfd, bfd_object, NULL))
{
//NSLog (@"GSBinaryFileInfo: BFD format object error");
[self release];
return nil;
}
// second read the symbols from it
if (!(bfd_get_file_flags (_abfd) & HAS_SYMS))
{
//NSLog (@"GSBinaryFileInfo: BFD does not contain any symbols");
[self release];
return nil;
}
neededSpace = bfd_get_symtab_upper_bound (_abfd);
if (neededSpace < 0)
{
//NSLog (@"GSBinaryFileInfo: BFD error while deducing needed space");
[self release];
return nil;
}
if (neededSpace == 0)
{
//NSLog (@"GSBinaryFileInfo: BFD no space for symbols needed");
[self release];
return nil;
}
_symbols = objc_malloc (neededSpace);
if (!_symbols)
{
//NSLog (@"GSBinaryFileInfo: Can't allocate buffer");
[self release];
return nil;
}
_symbolCount = bfd_canonicalize_symtab (_abfd, _symbols);
if (_symbolCount < 0)
{
//NSLog (@"GSBinaryFileInfo: BFD error while reading symbols");
[self release];
return nil;
}
return self;
}
struct SearchAddressStruct
{
void *theAddress;
GSBinaryFileInfo *module;
asymbol **symbols;
GSFunctionInfo *theInfo;
};
static void find_address (bfd *abfd, asection *section,
struct SearchAddressStruct *info)
{
bfd_vma address;
bfd_vma vma;
unsigned size;
const char *fileName;
const char *functionName;
unsigned line = 0;
if (info->theInfo)
{
return;
}
if (!(bfd_get_section_flags (abfd, section) & SEC_ALLOC))
{
return;
}
address = (bfd_vma) (intptr_t)info->theAddress;
vma = bfd_get_section_vma (abfd, section);
#if defined(bfd_get_section_size)
size = bfd_get_section_size (section); // recent
#else
size = bfd_section_size (abfd, section); // older version
#endif
if (address < vma || address >= vma + size)
{
return;
}
if (bfd_find_nearest_line (abfd, section, info->symbols,
address - vma, &fileName, &functionName, &line))
{
GSFunctionInfo *fi;
NSString *file = nil;
NSString *func = nil;
if (fileName != 0)
{
file = [NSString stringWithCString: fileName
encoding: [NSString defaultCStringEncoding]];
}
if (functionName != 0)
{
func = [NSString stringWithCString: functionName
encoding: [NSString defaultCStringEncoding]];
}
fi = [GSFunctionInfo alloc];
fi = [fi initWithModule: info->module
address: info->theAddress
file: file
function: func
line: line];
[fi autorelease];
info->theInfo = fi;
}
}
- (GSFunctionInfo *) functionForAddress: (void*) address
{
struct SearchAddressStruct searchInfo = { address, self, _symbols, nil };
bfd_map_over_sections (_abfd,
(void (*) (bfd *, asection *, void *)) find_address, &searchInfo);
return searchInfo.theInfo;
}
@end
static NSRecursiveLock *modLock = nil;
static NSMutableDictionary *stackModules = nil;
// initialize stack trace info
static id
GSLoadModule(NSString *fileName)
{
GSBinaryFileInfo *module = nil;
[modLock lock];
if (stackModules == nil)
{
NSEnumerator *enumerator;
NSBundle *bundle;
stackModules = [NSMutableDictionary new];
/*
* Try to ensure we have the main, base and gui library bundles.
*/
[NSBundle mainBundle];
[NSBundle bundleForClass: [NSObject class]];
[NSBundle bundleForClass: NSClassFromString(@"NSView")];
/*
* Add file info for all bundles with code.
*/
enumerator = [[NSBundle allBundles] objectEnumerator];
while ((bundle = [enumerator nextObject]) != nil)
{
if ([bundle load] == YES)
{
GSLoadModule([bundle executablePath]);
}
}
}
if ([fileName length] > 0)
{
module = [stackModules objectForKey: fileName];
if (module == nil);
{
module = [GSBinaryFileInfo infoWithBinaryFile: fileName];
if (module == nil)
{
module = (id)[NSNull null];
}
if ([stackModules objectForKey: fileName] == nil)
{
[stackModules setObject: module forKey: fileName];
}
else
{
module = [stackModules objectForKey: fileName];
}
}
}
[modLock unlock];
if (module == (id)[NSNull null])
{
module = nil;
}
return module;
}
#endif /* STACKSYMBOLS */
//
//
//
@implementation NSException (SOGoExtensions)
- (void) raise
{
#ifndef _NATIVE_OBJC_EXCEPTIONS
NSThread *thread;
NSHandler *handler;
#endif
if ([_e_info objectForKey: @"GSStackTraceKey"] == nil)
{
NSMutableDictionary *m;
if (_e_info == nil)
{
_e_info = m = [NSMutableDictionary new];
}
else if ([_e_info isKindOfClass: [NSMutableDictionary class]] == YES)
{
m = (NSMutableDictionary*)_e_info;
}
else
{
m = [_e_info mutableCopy];
RELEASE(_e_info);
_e_info = m;
}
[m setObject: [GSStackTrace currentStack] forKey: @"GSStackTraceKey"];
}
#ifdef _NATIVE_OBJC_EXCEPTIONS
@throw self;
#else
thread = GSCurrentThread();
handler = thread->_exception_handler;
if (handler == NULL)
{
static int recursion = 0;
/*
* Set/check a counter to prevent recursive uncaught exceptions.
* Allow a little recursion in case we have different handlers
* being tried.
*/
if (recursion++ > 3)
{
fprintf(stderr,
"recursion encountered handling uncaught exception\n");
fflush(stderr); /* NEEDED UNDER MINGW */
_terminate();
}
/*
* Call the uncaught exception handler (if there is one).
*/
if (_NSUncaughtExceptionHandler != NULL)
{
(*_NSUncaughtExceptionHandler)(self);
}
/*
* The uncaught exception handler which is set has not
* exited, so we call the builtin handler, (undocumented
* behavior of MacOS-X).
* The standard handler is guaranteed to exit/abort.
*/
_NSFoundationUncaughtExceptionHandler(self);
}
thread->_exception_handler = handler->next;
handler->exception = self;
longjmp(handler->jumpState, 1);
#endif
}
@end

View File

@ -51,6 +51,7 @@
#import "build.h"
#import "SOGoProductLoader.h"
#import "NSException+Stacktrace.h"
@interface SOGo : SoApplication
{

View File

@ -467,7 +467,6 @@ static BOOL showTextAttachmentsInline = NO;
[_info setObject: to forKey: @"to"];
/* CC processing if we reply-to-all: add all 'to' and 'cc' */
if (_replyToAll)
{
to = [NSMutableArray new];
@ -498,6 +497,17 @@ static BOOL showTextAttachmentsInline = NO;
[self _addEMailsOfAddresses: [_envelope from] toArray: to];
}
/* If we have no To but we have Cc recipients, let's move the Cc
to the To bucket... */
if ([[_info objectForKey: @"to"] count] == 0 && [_info objectForKey: @"cc"])
{
id o;
o = [_info objectForKey: @"cc"];
[_info setObject: o forKey: @"to"];
[_info removeObjectForKey: @"cc"];
}
[allRecipients release];
[addrs release];
}

View File

@ -144,6 +144,26 @@ static BOOL debugOn = NO;
return [clazz objectWithName: _key inContainer: self];
}
/* We overwrite the super's class method in order to make sure
we aren't dealing with our actual filename as the _key. That
could lead to problems if we weren't doing this as our filename
could start with a digit, leading to a wrong assumption in
the super class
*/
- (BOOL)isBodyPartKey:(NSString *)_key inContext:(id)_ctx
{
NSString *s;
s = [[[self partInfo] objectForKey: @"parameterList"] objectForKey: @"name"];
if (!s)
s = [[[[self partInfo] objectForKey: @"disposition"] objectForKey: @"parameterList"] objectForKey: @"filename"];
if (s && [s isEqualToString: _key]) return NO;
return [super isBodyPartKey: _key inContext: _ctx];
}
- (id) lookupName: (NSString *) _key
inContext: (id) _ctx
acquire: (BOOL) _flag

View File

@ -55,9 +55,18 @@
#import "SOGoGCSFolder.h"
static NSString *defaultUserID = @"<default>";
static BOOL sendFolderAdvisories = NO;
@implementation SOGoGCSFolder
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
sendFolderAdvisories = [ud boolForKey: @"SOGoFoldersSendEMailNotifications"];
}
+ (id) folderWithSubscriptionReference: (NSString *) reference
inContainer: (id) aContainer
{
@ -254,8 +263,6 @@ static NSString *defaultUserID = @"<default>";
[page send];
}
// if (!result) [self sendFolderAdvisoryTemplate: @"Addition"];
- (BOOL) create
{
NSException *result;
@ -264,6 +271,8 @@ static NSString *defaultUserID = @"<default>";
withName: displayName
atPath: ocsPath];
if (!result && sendFolderAdvisories) [self sendFolderAdvisoryTemplate: @"Addition"];
return (result == nil);
}
@ -280,11 +289,11 @@ static NSString *defaultUserID = @"<default>";
else
error = [[self folderManager] deleteFolderAtPath: ocsPath];
if (!error && sendFolderAdvisories) [self sendFolderAdvisoryTemplate: @"Removal"];
return error;
}
// if (!error) [self sendFolderAdvisoryTemplate: @"Removal"];
- (void) renameTo: (NSString *) newName
{
GCSChannelManager *cm;

View File

@ -21,16 +21,30 @@
*/
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/WORequest.h>
#import <SoObjects/SOGo/LDAPUserManager.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoObject.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <UI/SOGoUI/SOGoACLAdvisory.h>
#import <Foundation/NSUserDefaults.h>
#import "UIxUserRightsEditor.h"
static BOOL sendACLAdvisories = NO;
@implementation UIxUserRightsEditor
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"];
}
- (id) init
{
if ((self = [super init]))
@ -121,6 +135,25 @@
return response;
}
- (void) sendACLAdvisoryTemplateForObject: (id) theObject
{
NSString *language, *pageName;
SOGoUser *user;
SOGoACLAdvisory *page;
WOApplication *app;
user = [SOGoUser userWithLogin: uid roles: nil];
language = [user language];
pageName = [NSString stringWithFormat: @"SOGoACL%@ModificationAdvisory",
language];
app = [WOApplication application];
page = [app pageWithName: pageName inContext: context];
[page setACLObject: theObject];
[page setRecipientUID: uid];
[page send];
}
- (id <WOActionResults>) saveUserRightsAction
{
id <WOActionResults> response;
@ -130,8 +163,18 @@
reason: @"No such user."];
else
{
NSArray *o;
o = [NSArray arrayWithArray: userRights];
[self updateRights];
[[self clientObject] setRoles: userRights forUser: uid];
if (![o isEqualToArray: userRights] && sendACLAdvisories)
{
[self sendACLAdvisoryTemplateForObject: [self clientObject]];
}
response = [self jsCloseWithRefreshMethod: nil];
}

View File

@ -31,6 +31,7 @@
"edit" = "edit";
"invalidemailwarn" = "invalidemailwarn";
"new" = "new";
"Preferred Phone" = "Preferred Phone";
/* Folders */
"Personal Address Book" = "Personal Address Book";
@ -131,3 +132,5 @@
"The selected contact has no email address."
= "The selected contact has no email address.";
"Please select a contact." = "Please select a contact.";

View File

@ -38,6 +38,7 @@
"edit" = "Éditer";
"invalidemailwarn" = "Champ de l'email invalide, continuer quand même ?";
"new" = "Nouveau";
"Preferred Phone" = "Numéro préféré";
/* Folders */
"Personal Address Book" = "Carnet d'adresses personnel";
@ -145,3 +146,4 @@
"The selected contact has no email address."
= "Cette personne n'a pas d'adresse courriel.";
"Please select a contact." = "Veuillez sélectionner un contact..";

View File

@ -38,6 +38,7 @@
"edit" = "Éditer";
"invalidemailwarn" = "Champ de l'email invalide, continuer quand même ?";
"new" = "Neu";
"Preferred Phone" = "FIXME";
/* Folders */
"Personal Address Book" = "Personal Address Book";
@ -135,3 +136,5 @@
"The selected contact has no email address."
= "The selected contact has no email address.";
"Please select a contact." = "Bitte einen Kontakt auswählen.";

View File

@ -68,6 +68,15 @@
@interface SOGoACLGermanAdditionAdvisory : SOGoACLAdditionAdvisory
@end
@interface SOGoACLEnglishModificationAdvisory : SOGoACLAdditionAdvisory
@end
@interface SOGoACLFrenchModificationAdvisory : SOGoACLAdditionAdvisory
@end
@interface SOGoACLGermanModificationAdvisory : SOGoACLAdditionAdvisory
@end
@interface SOGoACLEnglishRemovalAdvisory : SOGoACLRemovalAdvisory
@end

View File

@ -97,6 +97,21 @@
return url;
}
- (NSString *) httpFolderURL
{
NSString *absoluteString;
NSMutableString *url;
#warning the url returned by SOGoMail may be empty, we need to handle that
absoluteString = [[aclObject soURL] absoluteString];
url = [NSMutableString stringWithString: absoluteString];
if (![url hasSuffix: @"/"])
[url appendString: @"/"];
return url;
}
- (NSString *) resourceName
{
return [aclObject nameInContainer];
@ -223,6 +238,12 @@
@end
@implementation SOGoACLModificationAdvisory
- (NSString *) aclMethod { return @"modify"; }
@end
@implementation SOGoACLEnglishAdditionAdvisory
@end
@ -232,6 +253,15 @@
@implementation SOGoACLGermanAdditionAdvisory
@end
@implementation SOGoACLEnglishModificationAdvisory
@end
@implementation SOGoACLFrenchModificationAdvisory
@end
@implementation SOGoACLGermanModificationAdvisory
@end
@implementation SOGoACLEnglishRemovalAdvisory
@end

View File

@ -423,3 +423,5 @@ vtodo_class2 = "(Confidential task)";
"closeThisWindowMessage" = "Thank you! You may now close this window or view your ";
"Multicolumn Day View" = "Multicolumn Day View";
"Please select an event or a task." = "Please select an event or a task.";

View File

@ -422,3 +422,5 @@ vtodo_class2 = "(Tâche confidentielle)";
"closeThisWindowMessage" = "Merci! Vous pouvez maintenant fermer cette fenêtre ou consulter votre ";
"Multicolumn Day View" = "Multicolonne";
"Please select an event or a task." = "Veuillez sélectionner un événement ou une tâche.";

View File

@ -411,3 +411,5 @@ vtodo_class2 = "(Confidential task)";
"closeThisWindowMessage" = "Vielen Dank! Sie können dieses Fenster jetzt schließen.";
"Multicolumn Day View" = "Multicolonne";
"Please select an event or a task." = "Veuillez sélectionner un événement ou une tâche.";

View File

@ -23,7 +23,7 @@
><td class="tbtv_headercell sortableTableHeader" id="orgHeader"
><var:string label:value="Organization" /></td
><td class="tbtv_headercell sortableTableHeader" id="phoneHeader"
><var:string label:value="Work Phone" /></td
><var:string label:value="Preferred Phone" /></td
></tr>
</thead>
<tbody>

View File

@ -13,10 +13,15 @@
<var:if condition="isBody">
<var:string value="currentUserName"/> has added you to the access list for his '<var:string value="resourceName"/>' folder.
You can subscribe directly to that folder by following this link:
<var:string value="httpAdvisoryURL"/>subscribe?mail-invitation=YES
Otherwise, you will be able to subscribe later from the SOGo web interface.
You can also access this resource remotely using the following URL:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<var:if condition="isSubject">
<var:string value="currentUserName"/> has modified the access rights
</var:if>
<var:if condition="isBody">
<var:string value="currentUserName"/> has modified your access rights for his '<var:string value="resourceName"/>' folder.
You can subscribe directly to that folder by following this link:
<var:string value="httpAdvisoryURL"/>subscribe?mail-invitation=YES
Otherwise, you will be able to subscribe later from the SOGo web interface.
You can also access this resource remotely using the following URL:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -13,10 +13,15 @@
<var:if condition="isBody">
<var:string value="currentUserName"/> has removed you from the access list for his '<var:string value="resourceName"/>' folder.
You can unsubscribe directly to that folder by following this link:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES
Otherwise, you will be able to unsubscribe later from the SOGo web interface.
You can also no longer access this resource using the following URL:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -8,15 +8,20 @@
xmlns:label="OGo:label">
<var:if condition="isSubject">
<var:string value="currentUserName"/> vous a ajouté
<var:string value="currentUserName"/> a modifié les droits
</var:if>
<var:if condition="isBody">
<var:string value="currentUserName"/> vous a ajouté a sa liste de permission pour son dossier '<var:string value="resourceName"/>'.
Vous pouvez vous inscrire directement a ce dossier en cliquant sur le lien suivant:
<var:string value="currentUserName"/> vous a ajouté à sa liste de permission pour son dossier '<var:string value="resourceName"/>'.
Vous pouvez vous inscrire directement à ce dossier en cliquant sur le lien suivant:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES
Autrement, il vous sera toujours possible de vous inscrire plus tard via l'interface web de SOGo.
De plus, vous pouvez aussi accéder au dossier en utilisant le lien suivant:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<var:if condition="isSubject">
<var:string value="currentUserName"/> vous a ajouté
</var:if>
<var:if condition="isBody">
<var:string value="currentUserName"/> a modifité vos droits d'accès pour son dossier '<var:string value="resourceName"/>'.
Vous pouvez vous inscrire directement à ce dossier en cliquant sur le lien suivant:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES
Autrement, il vous sera toujours possible de vous inscrire plus tard via l'interface web de SOGo.
De plus, vous pouvez aussi accéder au dossier en utilisant le lien suivant:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -13,10 +13,15 @@
<var:if condition="isBody">
<var:string value="currentUserName"/> vous a enlevé de sa liste de permission pour son dossier '<var:string value="resourceName"/>'.
Vous pouvez vous désinscrire directement en cliquant sur le lien suivant:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES
Autrement, il vous sera toujours possible de vous désinscrire plus tard via l'interface web de SOGo.
De plus, vous ne pouvez plus accéder au dossier en utilisant le lien suivant:
<var:string value="httpFolderURL"/>
</var:if>
</container>

View File

@ -13,6 +13,7 @@
<var:if condition="isBody">
<var:string value="currentUserName"/> hat Ihnen den Zugang zu seinem Ordner '<var:string value="resourceName"/>' erlaubt.
Folgende URL erlaubt Ihnen, sich sofort an diesem Ordner zu abonnieren:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES

View File

@ -0,0 +1,23 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<var:if condition="isSubject">
Zugangserlaubniss von <var:string value="currentUserName"/> erstellt
</var:if>
<var:if condition="isBody">
<var:string value="currentUserName"/> PLEASE TRANSLATE '<var:string value="resourceName"/>' XXXXXXXXXX.
Folgende URL erlaubt Ihnen, sich sofort an diesem Ordner zu abonnieren:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES
Sie können sich auch später immer noch durch die SOGo Webseiten abonnieren.
</var:if>
</container>

View File

@ -13,6 +13,7 @@
<var:if condition="isBody">
<var:string value="currentUserName"/> erlaubt Ihnen nicht mehr den Zugang zu seinem Order '<var:string value="resourceName"/>'.
Sie können sich sofort an folgender URL von diesem Order des-abonnieren:
<var:string value="httpAdvisoryURL"/>unsubscribe?mail-invitation=YES

View File

@ -310,20 +310,20 @@ function onMenuEditContact(event) {
}
function onMenuWriteToContact(event) {
var contactId = document.menuTarget.getAttribute('id');
var contactRow = $(contactId);
var emailCell = contactRow.down('td', 1);
var contactId = document.menuTarget.getAttribute('id');
var contactRow = $(contactId);
var emailCell = contactRow.down('td', 1);
if (!emailCell.firstChild) { // .nodeValue is the contact email address
window.alert(labels["The selected contact has no email address."]);
return false;
}
if (!emailCell.firstChild) { // .nodeValue is the contact email address
window.alert(labels["The selected contact has no email address."]);
return false;
}
openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+ "/" + contactId + "/write");
openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+ "/" + contactId + "/write");
if (document.body.hasClassName("popup"))
window.close();
if (document.body.hasClassName("popup"))
window.close();
}
function onMenuDeleteContact(event) {
@ -334,6 +334,11 @@ function onToolbarEditSelectedContacts(event) {
var contactsList = $('contactsList');
var rows = contactsList.getSelectedRowsId();
if (rows.length == 0) {
window.alert(labels["Please select a contact."]);
return false;
}
for (var i = 0; i < rows.length; i++) {
openContactWindow(URLForFolderID(currentContactFolder)
+ "/" + rows[i] + "/edit", rows[i]);
@ -347,8 +352,10 @@ function onToolbarWriteToSelectedContacts(event) {
var rows = contactsList.getSelectedRowsId();
var rowsWithEmail = 0;
if (rows.length == 0)
if (rows.length == 0) {
window.alert(labels["Please select a contact."]);
return false;
}
for (var i = 0; i < rows.length; i++) {
var emailCell = $(rows[i]).down('td', 1);
@ -373,6 +380,11 @@ function uixDeleteSelectedContacts(sender) {
var contactsList = $('contactsList');
var rows = contactsList.getSelectedRowsId();
if (rows.length == 0) {
window.alert(labels["Please select a contact."]);
return false;
}
var contactView = $('contactView');
contactView.innerHTML = '';

View File

@ -81,12 +81,19 @@ function editEvent() {
if (listOfSelection) {
var nodes = listOfSelection.getSelectedRows();
if (nodes.length == 0) {
window.alert(labels["Please select an event or a task."]);
return false;
}
for (var i = 0; i < nodes.length; i++)
_editEventId(nodes[i].getAttribute("id"),
nodes[i].calendar);
} else if (selectedCalendarCell) {
_editEventId(selectedCalendarCell[0].cname,
selectedCalendarCell[0].calendar);
_editEventId(selectedCalendarCell[0].cname,
selectedCalendarCell[0].calendar);
} else {
window.alert(labels["Please select an event or a task."]);
}
return false; /* stop following the link */
@ -135,6 +142,8 @@ function deleteEvent() {
}
_batchDeleteEvents();
}
} else {
window.alert(labels["Please select an event or a task."]);
}
}
else if (selectedCalendarCell) {
@ -150,7 +159,7 @@ function deleteEvent() {
}
}
else
window.alert("no selection");
window.alert(labels["Please select an event or a task."]);
return false;
}