]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1068 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 22 May 2007 21:19:22 +0000 (21:19 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 22 May 2007 21:19:22 +0000 (21:19 +0000)
48 files changed:
ChangeLog
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Appointments/SOGoFreeBusyObject.m
SoObjects/Mailer/SOGoMailFolder.h
SoObjects/Mailer/SOGoMailFolder.m
SoObjects/Mailer/SOGoMailObject.m
SoObjects/SOGo/NSArray+Utilities.h
SoObjects/SOGo/NSArray+Utilities.m
SoObjects/SOGo/SOGoContentObject.m
SoObjects/SOGo/SOGoFolder.h
SoObjects/SOGo/SOGoFolder.m
SoObjects/SOGo/SOGoObject.h
SoObjects/SOGo/SOGoObject.m
SoObjects/SOGo/SOGoPermissions.h
SoObjects/SOGo/SOGoPermissions.m
UI/Common/UIxAclEditor.h
UI/Common/UIxAclEditor.m
UI/Common/UIxUserRightsEditor.h
UI/Common/UIxUserRightsEditor.m
UI/Contacts/English.lproj/Localizable.strings
UI/Contacts/French.lproj/Localizable.strings
UI/MailPartViewers/UIxMailPartTextViewer.m
UI/MailerUI/English.lproj/Localizable.strings
UI/MailerUI/French.lproj/Localizable.strings
UI/MailerUI/GNUmakefile
UI/MailerUI/UIxMailFolderACLEditor.m [deleted file]
UI/MailerUI/UIxMailUserRightsEditor.h [new file with mode: 0644]
UI/MailerUI/UIxMailUserRightsEditor.m [new file with mode: 0644]
UI/MailerUI/product.plist
UI/Scheduler/English.lproj/Localizable.strings
UI/Scheduler/French.lproj/Localizable.strings
UI/Templates/ContactsUI/UIxContactsFilterPanel.wox
UI/Templates/ContactsUI/UIxContactsListViewContainer.wox
UI/Templates/MailerUI/UIxMailFolderACLEditor.wox [deleted file]
UI/Templates/MailerUI/UIxMailMainFrame.wox
UI/Templates/MailerUI/UIxMailUserRightsEditor.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalFilterPanel.wox
UI/Templates/SchedulerUI/UIxCalMainView.wox
UI/Templates/UIxAclEditor.wox
UI/WebServerResources/ContactsUI.js
UI/WebServerResources/HTMLElement.js
UI/WebServerResources/MailerUI.js
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxAclEditor.js
UI/WebServerResources/UIxMailUserRightsEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxMailUserRightsEditor.js [new file with mode: 0644]
UI/WebServerResources/generic.css
UI/WebServerResources/generic.js

index 06b9a6f5e15c2afae7a110f13c1f2978b5a4e95b..c142c23e5b55f2be2f4dfd52a9a7173a30a3680b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,82 @@
+2007-05-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
+       -isDeletionAllowed]): completed method with the new imap acl api.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -defaultAclRoles]):
+       removed method.
+
+       * SoObjects/SOGo/SOGoPermissions.m: added the new role
+       "SOGoMailRole_MessageEraser".
+
+       * UI/Common/UIxAclEditor.m ([UIxAclEditor -defaultUserID]) 
+       ([UIxAclEditor -_prepareUsers]): take the new SOGoObject's
+       "defaultUserID" method into account.
+
+       * UI/Common/UIxUserRightsEditor.m ([UIxUserRightsEditor -userIsDefaultUser]) 
+       ([UIxUserRightsEditor -_initRights]): take the new SOGoObject's
+       "defaultUserID" method into account.
+
+       * UI/MailerUI/UIxMailUserRightsEditor.m: added all the missing
+       methods to support the IMAP acls mentionned in the RFC 4314,
+       removed the ones specific to Cyrus.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -defaultUserID]): new
+       mandatory method for subclasses. Removed the SOGoDefaultUserID
+       global var.
+
+       * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -defaultUserID]):
+       overriden method to return @"<default>".
+
+       * SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
+       -defaultUserID]): overriden method to return @"<default>".
+
+       * SoObjects/Mailer/SOGoMailFolder.m ([SOGoMailFolder
+       -aclsForUser:uid]): overriden method.
+       ([SOGoMailFolder -removeAclsForUsers:users]): overriden method.
+       ([SOGoMailFolder -setRoles:rolesforUser:uid]): overriden method.
+       ([SOGoMailFolder -defaultUserID]): overriden method.
+       ([SOGoMailFolder -hasSupportForDefaultRoles]): overriden method.
+
+2007-05-18  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
+       -aclUsersForObjectAtPath:objectPathArray]): new method that being
+       forwarded the calles to aclUsers for the GCS-based subclasses of
+       SOGoObject.
+
+       * SoObjects/Mailer/SOGoMailFolder.m: removed all the previous
+       methods that would have been used to support IMAP acls. Replaced
+       them with the new protocol for them that has been implemented in
+       SOGo during the last few weeks.
+
+       * SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
+       -hasSupportForDefaultRoles]): override method by returning "YES".
+
+       * SoObjects/SOGo/NSArray+Utilities.m ([NSMutableArray
+       -addObjectUniquely:object]): new method with an explicit name.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -aclUsers]): renamed
+       "acl" to "aclUsers". Now designed to return only the uid of the
+       users involved in an ACL.
+       ([SOGoObject -hasSupportForDefaultRoles]): new method returning
+       "NO" by default. To indicate to the acl editor that we don't want
+       to handle a default user.
+
+       * SoObjects/SOGo/SOGoPermissions.[hm]: added the
+       SOGoRole_ObjectReader, SOGoRole_Folder*, and SOGoMailRole_*
+       symbols.
+
+       * UI/MailerUI/UIxMailUserRightsEditor.[hm]: new class module that
+       provides a view to the IMAP acls.
+
+       * UI/MailerUI/UIxMailFolderACLEditor.m: removed obsolete module.
+
+       * UI/WebServerResources/MailerUI.js: replaced all invocations of
+       addEventListener to the use of prototype's Event object. Also,
+       configured all menus programmatically following descriptions lists
+       containing their callbacks, or nulls, submenus id or separators.
+
 2007-05-17  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/Common/UIxObjectActions.m ([UIxObjectActions
index 5d708c38f4aafd9a5504d75c18d5b0991cd92bdc..a2cea22aca7e2da6959ddbb38b6303d4f5dc6ba7 100644 (file)
@@ -1296,13 +1296,4 @@ static NSNumber   *sharedYes = nil;
   return @"IPF.Appointment";
 }
 
-/* acls */
-- (NSArray *) defaultAclRoles
-{
-  return [NSArray arrayWithObjects:
-                   SOGoCalendarRole_PublicViewer,
-                 SOGoCalendarRole_ConfidentialDAndTViewer,
-                 nil];
-}
-
 @end /* SOGoAppointmentFolder */
index 724821d56be39e4e0df2e40a2ae7f4dcddf57dfa..ae378a123822c5af27c8d58eb08bafb31b649d49 100644 (file)
@@ -18,7 +18,6 @@
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
 #import <NGCards/iCalCalendar.h>
 #import <NGCards/iCalFreeBusy.h>
index ce49d2a4c5421b146410bc67e9238083f5f1ede4..a698bdaaaed0f5b356de1af2a90d9e70be76c058 100644 (file)
   NSArray            *filenames;
   NSString           *folderType;
   NGImap4MailboxInfo *selectInfo;
-  struct {
-    int didCheckMyRights:1;
-    int isDeleteAndExpungeAllowed:1;
-    int isReadAllowed:1;
-    int isWriteAllowed:1;
-    int isInsertAllowed:1;
-    int isPostAllowed:1;
-    int isCreateAllowed:1;
-    int hasAdminAccess:1;
-    int reserved:24;
-  } somfFlags;
 }
 
 /* messages */
 
 - (NSException *)expunge;
 
-/* permissions */
-
-- (BOOL)isDeleteAndExpungeAllowed;
-- (BOOL)isReadAllowed;
-- (BOOL)isWriteAllowed;
-- (BOOL)isInsertAllowed;
-- (BOOL)isPostAllowed;
-- (BOOL)isCreateAllowed;
-- (BOOL)hasAdminAccess;
-
 /* flags */
 
 - (NSException *)addFlagsToAllMessages:(id)_f;
index cf537404ab475c03c2e22b2bd8df5118aaed11eb..6c7c84cb1a6a68a16675e9af06d39c4adede04b6 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoMailFolder.h"
-#include "SOGoMailObject.h"
-#include "SOGoMailAccount.h"
-#include "SOGoMailManager.h"
-#include <NGImap4/NGImap4MailboxInfo.h>
-#include "SOGoMailFolderDataSource.h"
-#include "common.h"
+#import <Foundation/NSUserDefaults.h>
+
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGExtensions/NSNull+misc.h>
+#import <NGExtensions/NSURL+misc.h>
+#import <NGExtensions/NSObject+Logs.h>
+
+#import <NGImap4/NGImap4Connection.h>
+#import <NGImap4/NGImap4MailboxInfo.h>
+#import <NGImap4/NGImap4Client.h>
+
+#import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/NSArray+Utilities.h>
+
+#import "SOGoMailObject.h"
+#import "SOGoMailAccount.h"
+#import "SOGoMailManager.h"
+#import "SOGoMailFolderDataSource.h"
+#import "SOGoMailFolder.h"
+
+static NSString *defaultUserID =  @"anyone";
 
 @implementation SOGoMailFolder
 
@@ -46,9 +60,9 @@ static BOOL useAltNamespace = NO;
 }
 
 - (void)dealloc {
-  [self->selectInfo release];
-  [self->filenames  release];
-  [self->folderType release];
+  [selectInfo release];
+  [filenames  release];
+  [folderType release];
   [super dealloc];
 }
 
@@ -68,15 +82,15 @@ static BOOL useAltNamespace = NO;
   NSArray  *uids;
   unsigned count;
   
-  if (self->filenames != nil)
-    return [self->filenames isNotNull] ? self->filenames : nil;
+  if (filenames != nil)
+    return [filenames isNotNull] ? filenames : nil;
 
   uids = [self fetchUIDsMatchingQualifier:nil sortOrdering:@"DATE"];
   if ([uids isKindOfClass:[NSException class]])
     return nil;
   
   if ((count = [uids count]) == 0) {
-    self->filenames = [[NSArray alloc] init];
+    filenames = [[NSArray alloc] init];
   }
   else {
     NSMutableArray *keys;
@@ -90,10 +104,10 @@ static BOOL useAltNamespace = NO;
       k = [k stringByAppendingString:@".mail"];
       [keys addObject:k];
     }
-    self->filenames = [keys copy];
+    filenames = [keys copy];
     [keys release];
   }
-  return self->filenames;
+  return filenames;
 }
 
 - (EODataSource *)contentDataSourceInContext:(id)_ctx {
@@ -110,98 +124,17 @@ static BOOL useAltNamespace = NO;
   /* returns nil if fetch was successful */
   id info;
   
-  if (self->selectInfo != nil)
+  if (selectInfo != nil)
     return nil; /* select info exists, => no error */
   
   info = [[self imap4Connection] infoForMailboxAtURL:[self imap4URL]];
   if ([info isKindOfClass:[NSException class]])
     return info;
   
-  self->selectInfo = [info retain];
+  selectInfo = [info retain];
   return nil; /* no error */
 }
 
-/* permissions */
-
-- (void)_loadACLPermissionFlags {
-  NSString *rights;
-  unsigned i, len;
-  
-  if (self->somfFlags.didCheckMyRights)
-    return;
-
-  rights = [[self imap4Connection] myRightsForMailboxAtURL:[self imap4URL]];
-  if ([rights isKindOfClass:[NSException class]]) {
-    [self logWithFormat:@"ERROR: could not retrieve ACL: %@", rights];
-    return;
-  }
-  
-  // [self logWithFormat:@"GOT PERM: %@", rights];
-  
-  self->somfFlags.didCheckMyRights = 1;
-  
-  /* reset flags */
-  self->somfFlags.isDeleteAndExpungeAllowed = 0;
-  self->somfFlags.isReadAllowed   = 0;
-  self->somfFlags.isWriteAllowed  = 0;
-  self->somfFlags.isInsertAllowed = 0;
-  self->somfFlags.isPostAllowed   = 0;
-  self->somfFlags.isCreateAllowed = 0;
-  self->somfFlags.hasAdminAccess  = 0;
-  
-  for (i = 0, len = [rights length]; i < len; i++) {
-    switch ([rights characterAtIndex:i]) {
-    case 'd': self->somfFlags.isDeleteAndExpungeAllowed = 1; break;
-    case 'r': self->somfFlags.isReadAllowed   = 1; break;
-    case 'w': self->somfFlags.isWriteAllowed  = 1; break;
-    case 'i': self->somfFlags.isInsertAllowed = 1; break;
-    case 'p': self->somfFlags.isPostAllowed   = 1; break;
-    case 'c': self->somfFlags.isCreateAllowed = 1; break;
-    case 'a': self->somfFlags.hasAdminAccess  = 1; break;
-    }
-  }
-}
-
-- (BOOL)isDeleteAndExpungeAllowed {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isDeleteAndExpungeAllowed ? YES : NO;
-}
-- (BOOL)isReadAllowed {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isReadAllowed ? YES : NO;
-}
-- (BOOL)isWriteAllowed {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isWriteAllowed ? YES : NO;
-}
-- (BOOL)isInsertAllowed {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isInsertAllowed ? YES : NO;
-}
-- (BOOL)isPostAllowed {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isPostAllowed ? YES : NO;
-}
-
-- (BOOL)isCreateAllowedInACL {
-  /* we call this directly from UIxMailAccountView */
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.isCreateAllowed ? YES : NO;
-}
-- (BOOL)isCreateAllowed {
-  if (useAltNamespace) {
-    /* with altnamespace, Cyrus doesn't allow mailboxes under INBOX */
-    if ([[self outlookFolderClass] isEqualToString:@"IPF.Inbox"])
-      return NO;
-  }
-  return [self isCreateAllowedInACL];
-}
-
-- (BOOL)hasAdminAccess {
-  [self _loadACLPermissionFlags];
-  return self->somfFlags.hasAdminAccess ? YES : NO;
-}
-
 /* messages */
 
 - (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so {
@@ -369,22 +302,181 @@ static BOOL useAltNamespace = NO;
   SOGoMailAccount *account;
   NSString *n;
 
-  if (self->folderType != nil)
-    return self->folderType;
+  if (folderType != nil)
+    return folderType;
   
   account = [self mailAccountFolder];
   n       = [self nameInContainer];
   
   if ([n isEqualToString:[account trashFolderNameInContext:nil]])
-    self->folderType = @"IPF.Trash";
+    folderType = @"IPF.Trash";
   else if ([n isEqualToString:[account inboxFolderNameInContext:nil]])
-    self->folderType = @"IPF.Inbox";
+    folderType = @"IPF.Inbox";
   else if ([n isEqualToString:[account sentFolderNameInContext:nil]])
-    self->folderType = @"IPF.Sent";
+    folderType = @"IPF.Sent";
   else
-    self->folderType = @"IPF.Folder";
+    folderType = @"IPF.Folder";
   
-  return self->folderType;
+  return folderType;
+}
+
+/* acls */
+
+- (NSArray *) _imapAclsToSOGoAcls: (NSString *) imapAcls
+{
+  unsigned int count, max;
+  NSMutableArray *SOGoAcls;
+
+  SOGoAcls = [NSMutableArray array];
+  max = [imapAcls length];
+  for (count = 0; count < max; count++)
+    {
+      switch ([imapAcls characterAtIndex: count])
+       {
+       case 'l':
+         [SOGoAcls addObjectUniquely: SOGoRole_ObjectViewer];
+         break;
+       case 'r':
+         [SOGoAcls addObjectUniquely: SOGoRole_ObjectReader];
+         break;
+       case 's':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_SeenKeeper];
+         break;
+       case 'w':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_Writer];
+         break;
+       case 'i':
+         [SOGoAcls addObjectUniquely: SOGoRole_ObjectCreator];
+         break;
+       case 'p':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_Poster];
+         break;
+       case 'k':
+         [SOGoAcls addObjectUniquely: SOGoRole_FolderCreator];
+         break;
+       case 'x':
+         [SOGoAcls addObjectUniquely: SOGoRole_ObjectEraser];
+         break;
+       case 't':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_MessageEraser];
+         break;
+       case 'e':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_Expunger];
+         break;
+       case 'a':
+         [SOGoAcls addObjectUniquely: SOGoMailRole_Administrator];
+         break;
+       }
+    }
+
+  return SOGoAcls;
+}
+
+- (NSString *) _sogoAclsToImapAcls: (NSArray *) sogoAcls
+{
+  NSMutableString *imapAcls;
+  NSEnumerator *acls;
+  NSString *currentAcl;
+  char character;
+
+  imapAcls = [NSMutableString string];
+  acls = [sogoAcls objectEnumerator];
+  currentAcl = [acls nextObject];
+  while (currentAcl)
+    {
+      if ([currentAcl isEqualToString: SOGoRole_ObjectViewer])
+       character = 'l';
+      else if ([currentAcl isEqualToString: SOGoRole_ObjectReader])
+       character = 'r';
+      else if ([currentAcl isEqualToString: SOGoMailRole_SeenKeeper])
+       character = 's';
+      else if ([currentAcl isEqualToString: SOGoMailRole_Writer])
+       character = 'w';
+      else if ([currentAcl isEqualToString: SOGoRole_ObjectCreator])
+       character = 'i';
+      else if ([currentAcl isEqualToString: SOGoMailRole_Poster])
+       character = 'p';
+      else if ([currentAcl isEqualToString: SOGoRole_FolderCreator])
+       character = 'k';
+      else if ([currentAcl isEqualToString: SOGoRole_ObjectEraser])
+       character = 'x';
+      else if ([currentAcl isEqualToString: SOGoMailRole_MessageEraser])
+       character = 't';
+      else if ([currentAcl isEqualToString: SOGoMailRole_Expunger])
+       character = 'e';
+      else if ([currentAcl isEqualToString: SOGoMailRole_Administrator])
+       character = 'a';
+      else
+       character = 0;
+
+      if (character)
+       [imapAcls appendFormat: @"%c", character];
+
+      currentAcl = [acls nextObject];
+    }
+
+  return imapAcls;
+}
+
+- (NSArray *) aclUsers
+{
+  NSDictionary *imapAcls;
+
+  imapAcls = [imap4 aclForMailboxAtURL: [self imap4URL]];
+
+  return [imapAcls allKeys];
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+  NSDictionary *imapAcls;
+  NSString *userAcls;
+
+  imapAcls = [imap4 aclForMailboxAtURL: [self imap4URL]];
+  userAcls = [imapAcls objectForKey: uid];
+  if (!([userAcls length] || [uid isEqualToString: defaultUserID]))
+    userAcls = [imapAcls objectForKey: defaultUserID];
+
+  return [self _imapAclsToSOGoAcls: userAcls];
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+{
+  NSEnumerator *uids;
+  NSString *currentUID;
+  NSString *folderName;
+  NGImap4Client *client;
+
+  folderName = [imap4 imap4FolderNameForURL: [self imap4URL]];
+  client = [imap4 client];
+
+  uids = [users objectEnumerator];
+  currentUID = [uids nextObject];
+  while (currentUID)
+    {
+      [client deleteACL: folderName uid: currentUID];
+      currentUID = [uids nextObject];
+    }
+}
+
+- (void) setRoles: (NSArray *) roles
+         forUser: (NSString *) uid
+{
+  NSString *acls, *folderName;
+
+  acls = [self _sogoAclsToImapAcls: roles];
+  folderName = [imap4 imap4FolderNameForURL: [self imap4URL]];
+  [[imap4 client] setACL: folderName rights: acls uid: uid];
+}
+
+- (NSString *) defaultUserID
+{
+  return defaultUserID;
+}
+
+- (BOOL) hasSupportForDefaultRoles
+{
+  return YES;
 }
 
 @end /* SOGoMailFolder */
index 749882e168842f4b78d0bd0d4f840d95e9e075e9..68ec6326ad6925dc6f9e9cddffbb6bf55424ff7f 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoMailObject.h"
-#include "SOGoMailFolder.h"
-#include "SOGoMailAccount.h"
-#include "SOGoMailManager.h"
-#include "SOGoMailBodyPart.h"
-#include <NGImap4/NGImap4Envelope.h>
-#include <NGImap4/NGImap4EnvelopeAddress.h>
-#include <NGMail/NGMimeMessageParser.h>
-#include "common.h"
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSEnumerator.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSUserDefaults.h>
+#import <Foundation/NSValue.h>
+
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGExtensions/NGBase64Coding.h>
+#import <NGExtensions/NSNull+misc.h>
+#import <NGExtensions/NSObject+Logs.h>
+#import <NGExtensions/NGQuotedPrintableCoding.h>
+#import <NGExtensions/NSString+Encoding.h>
+#import <NGImap4/NGImap4Connection.h>
+#import <NGImap4/NGImap4Envelope.h>
+#import <NGImap4/NGImap4EnvelopeAddress.h>
+#import <NGMail/NGMimeMessageParser.h>
+
+#import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/SOGoUser.h>
+#import "SOGoMailFolder.h"
+#import "SOGoMailAccount.h"
+#import "SOGoMailManager.h"
+#import "SOGoMailBodyPart.h"
+
+#import "SOGoMailObject.h"
 
 @implementation SOGoMailObject
 
@@ -639,8 +659,15 @@ static BOOL debugSoParts       = NO;
 
 /* permissions */
 
-- (BOOL)isDeletionAllowed {
-  return [[self container] isDeleteAndExpungeAllowed];
+- (BOOL) isDeletionAllowed
+{
+  NSArray *parentAcl;
+  NSString *login;
+
+  login = [[context activeUser] login];
+  parentAcl = [[self container] aclsForUser: login];
+
+  return [parentAcl containsObject: SOGoMailRole_MessageEraser];
 }
 
 /* name lookup */
index 15cbb174be29e4f16fdfee6c874685febb9fe981..2617538d34b13d2d4df28ede5fa0f77fc2caccbd 100644 (file)
 
 @end
 
+@interface NSMutableArray (SOGoArrayUtilities)
+
+- (void) addObjectUniquely: (id) object;
+
+@end
+
 #endif /* NSARRAY_UTILITIES_H */
index ed30b5e5af473c700dfa5d032661d66839ac4728..75dec348cb7dc260e313b13542e03c0a3eaa539d 100644 (file)
 }
 
 @end
+
+@implementation NSMutableArray (SOGoArrayUtilities)
+
+- (void) addObjectUniquely: (id) object
+{
+  if (![self containsObject: object])
+    [self addObject: object];
+}
+
+@end
+
index ed75b3ce3320a93657ff468ad6d2b72941ed90c9..e2b11a44ef3ee7cfdfec9a5b646bbb6557123559 100644 (file)
     : 0 /* 0 means 'do not check' */;
   
   /* attempt a save */
-  
-  if ((error = [self saveContentString:[rq contentAsString]
-                    baseVersion:baseVersion]) != nil)
+
+  if ((error = [self saveContentString: [rq contentAsString]
+                    baseVersion: baseVersion]) != nil)
     return error;
   
   /* setup response */
 
 /* acls */
 
-- (NSArray *) acls
+- (NSArray *) aclUsers
 {
-  return [container aclsForObjectAtPath: [self pathArrayToSoObject]];
+  return [container aclUsersForObjectAtPath: [self pathArrayToSoObject]];
 }
 
 - (NSArray *) aclsForUser: (NSString *) uid
                     forObjectAtPath: [self pathArrayToSoObject]];
 }
 
+- (NSString *) defaultUserID
+{
+  return @"<default>";
+}
+
+- (BOOL) hasSupportForDefaultRoles
+{
+  return YES;
+}
+
 /* message type */
 
 - (NSString *) outlookMessageClass
index b5527d4988c6d468cf6e21f261dd2a2f518a4dcb..a6aaf18d629fa20c0da27d3f59be65f1c59edc0a 100644 (file)
@@ -72,7 +72,7 @@
 - (NSException *) delete;
 
 /* acls as a container */
-- (NSArray *) aclsForObjectAtPath: (NSArray *) objectPathArray;
+- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
 - (NSArray *) aclsForUser: (NSString *) uid
           forObjectAtPath: (NSArray *) objectPathArray;
 - (void) setRoles: (NSArray *) roles
index a55c3dad258e513a0da273b17b15e06f806763b1..2e3b7469f22580a8a72f7bea2d15cba166ff57cc 100644 (file)
@@ -31,6 +31,8 @@
 #import <unistd.h>
 #import <stdlib.h>
 
+static NSString *defaultUserID = @"<default>";
+
 @implementation SOGoFolder
 
 + (int) version
 
 /* acls as a container */
 
-- (NSArray *) aclsForObjectAtPath: (NSArray *) objectPathArray;
+- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
 {
   EOQualifier *qualifier;
   NSString *qs;
+  NSArray *records;
 
   qs = [NSString stringWithFormat: @"c_object = '/%@'",
                 [objectPathArray componentsJoinedByString: @"/"]];
   qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+  records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
 
-  return [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
+  return [records valueForKey: @"c_uid"];
 }
 
 - (NSArray *) _fetchAclsForUser: (NSString *) uid
       [self _cacheRoles: acls forUser: uid forObjectAtPath: objectPath];
     }
 
-  if (!([acls count] || [uid isEqualToString: SOGoDefaultUserID]))
-    acls = [self aclsForUser: SOGoDefaultUserID
+  if (!([acls count] || [uid isEqualToString: defaultUserID]))
+    acls = [self aclsForUser: defaultUserID
                 forObjectAtPath: objectPathArray];
 
   return acls;
 }
 
 /* acls */
-- (NSArray *) defaultAclRoles
-{
-#warning this should be changed to something useful
-  return nil;
-}
-
-- (NSArray *) acls
+- (NSArray *) aclUsers
 {
-  return [self aclsForObjectAtPath: [self pathArrayToSoObject]];
+  return [self aclUsersForObjectAtPath: [self pathArrayToSoObject]];
 }
 
 - (NSArray *) aclsForUser: (NSString *) uid
                forObjectAtPath: [self pathArrayToSoObject]];
 }
 
+- (NSString *) defaultUserID
+{
+  return defaultUserID;
+}
+
+- (BOOL) hasSupportForDefaultRoles
+{
+  return YES;
+}
+
 /* WebDAV */
 
 - (BOOL) davIsCollection
index e5a77e73921c734ac7a93595fea0de4c53a44a9a..b265699efa6ea700cc9de240da08eeedb45e19d5 100644 (file)
@@ -52,8 +52,6 @@
 
 #define $(class) NSClassFromString(class)
 
-extern NSString *SOGoDefaultUserID;
-
 @interface SOGoObject : NSObject
 {
   WOContext *context;
@@ -100,12 +98,13 @@ extern NSString *SOGoDefaultUserID;
 
 /* acls */
 
-- (NSArray *) defaultAclRoles;
-- (NSArray *) acls;
+- (NSArray *) aclUsers;
 - (NSArray *) aclsForUser: (NSString *) uid;
 - (void) setRoles: (NSArray *) roles
           forUser: (NSString *) uid;
 - (void) removeAclsForUsers: (NSArray *) users;
+- (NSString *) defaultUserID;
+- (BOOL) hasSupportForDefaultRoles;
 
 /* description */
 
index 57b13cd78a0858d6b4a53609943ed59400b84fe9..5ca5809f75ea623ce7b2789bb784495f79c1db20 100644 (file)
@@ -47,8 +47,6 @@
 
 #import "SOGoObject.h"
 
-NSString *SOGoDefaultUserID = @"<default>";
-
 @interface SOGoObject(Content)
 - (NSString *)contentAsString;
 @end
@@ -354,23 +352,23 @@ static BOOL kontactGroupDAV = YES;
 
 - (SOGoDAVSet *) davAcl
 {
-  NSArray *role;
-  NSEnumerator *acls;
+  NSArray *roles;
+  NSEnumerator *uids;
   NSMutableDictionary *aclsDictionary;
-  NSDictionary *currentAcl;
+  NSString *currentUID;
   SoClassSecurityInfo *sInfo;
 
-  acls = [[self acls] objectEnumerator];
   aclsDictionary = [NSMutableDictionary dictionary];
+  uids = [[self aclUsers] objectEnumerator];
   sInfo = [[self class] soClassSecurityInfo];
 
-  currentAcl = [acls nextObject];
-  while (currentAcl)
+  currentUID = [uids nextObject];
+  while (currentUID)
     {
-      role = [NSArray arrayWithObject: [currentAcl objectForKey: @"role"]];
-      [aclsDictionary setObject: [sInfo DAVPermissionsForRoles: role]
-                      forKey: [currentAcl objectForKey: @"uid"]];
-      currentAcl = [acls nextObject];
+      roles = [self aclsForUser: currentUID];
+      [aclsDictionary setObject: [sInfo DAVPermissionsForRoles: roles]
+                      forKey: currentUID];
+      currentUID = [uids nextObject];
     }
   [self _appendRolesForPseudoPrincipals: aclsDictionary
         withClassSecurityInfo: sInfo];
@@ -707,7 +705,7 @@ static BOOL kontactGroupDAV = YES;
 
 /* acls */
 
-- (NSArray *) acls
+- (NSArray *) aclUsers
 {
   [self subclassResponsibility: _cmd];
 
@@ -721,22 +719,27 @@ static BOOL kontactGroupDAV = YES;
   return nil;
 }
 
-- (NSArray *) defaultAclRoles
+- (void) setRoles: (NSArray *) roles
+          forUser: (NSString *) uid
 {
   [self subclassResponsibility: _cmd];
-
-  return nil;
 }
 
-- (void) setRoles: (NSArray *) roles
-          forUser: (NSString *) uid
+- (void) removeAclsForUsers: (NSArray *) users
 {
   [self subclassResponsibility: _cmd];
 }
 
-- (void) removeAclsForUsers: (NSArray *) users
+- (NSString *) defaultUserID
 {
   [self subclassResponsibility: _cmd];
+
+  return nil;
+}
+
+- (BOOL) hasSupportForDefaultRoles
+{
+  return NO;
 }
 
 /* description */
index 67ee64bee0b48ac0bf91b743846eba4bb7d87298..2b4e60cf55c12ce113ef315e59961b0cb77ae7dd 100644 (file)
 #import <NGObjWeb/SoPermissions.h>
 
 extern NSString *SOGoRole_ObjectCreator;
+extern NSString *SOGoRole_ObjectReader;
 extern NSString *SOGoRole_ObjectEraser;
 extern NSString *SOGoRole_ObjectViewer;
 extern NSString *SOGoRole_ObjectEditor;
+
+extern NSString *SOGoRole_FolderCreator;
+extern NSString *SOGoRole_FolderReader;
 extern NSString *SOGoRole_AuthorizedSubscriber;
 extern NSString *SOGoRole_None;
-
 extern NSString *SOGoRole_FreeBusy;
 extern NSString *SOGoRole_FreeBusyLookup;
 
-extern NSString *SOGoPerm_ReadAcls;
-extern NSString *SOGoPerm_FreeBusyLookup;
+extern NSString *SOGoMailRole_SeenKeeper;
+extern NSString *SOGoMailRole_Writer;
+extern NSString *SOGoMailRole_Poster;
+extern NSString *SOGoMailRole_Expunger;
+extern NSString *SOGoMailRole_Creator;
+extern NSString *SOGoMailRole_Administrator;
+extern NSString *SOGoMailRole_MessageEraser;
 
 extern NSString *SOGoCalendarRole_Organizer;
 extern NSString *SOGoCalendarRole_Participant;
@@ -61,6 +69,9 @@ extern NSString *SOGoCalendarRole_ComponentDAndTViewer;
 extern NSString *SOGoCalendarRole_ComponentModifier;
 extern NSString *SOGoCalendarRole_ComponentResponder;
 
+extern NSString *SOGoPerm_ReadAcls;
+extern NSString *SOGoPerm_FreeBusyLookup;
+
 extern NSString *SOGoCalendarPerm_ViewWholePublicRecords;
 extern NSString *SOGoCalendarPerm_ViewDAndTOfPublicRecords;
 extern NSString *SOGoCalendarPerm_ModifyPublicRecords;
index e750ef31b8c459306073f3837674d458c8d8720d..f5cb1f172b20e22a9fe9a12b30dd3b2d58b46cd4 100644 (file)
 NSString *SOGoRole_ObjectCreator = @"ObjectCreator";
 NSString *SOGoRole_ObjectEraser = @"ObjectEraser";
 NSString *SOGoRole_ObjectViewer = @"ObjectViewer";
+NSString *SOGoRole_ObjectReader = @"ObjectReader";
 NSString *SOGoRole_ObjectEditor = @"ObjectEditor";
+NSString *SOGoRole_FolderCreator = @"FolderCreator";
+NSString *SOGoRole_FolderEraser = @"FolderEraser";
+NSString *SOGoRole_FolderViewer = @"FolderViewer";
+NSString *SOGoRole_FolderReader = @"FolderReader";
 NSString *SOGoRole_AuthorizedSubscriber = @"AuthorizedSubscriber";
 NSString *SOGoRole_None = @"None";
 
@@ -60,6 +65,13 @@ NSString *SOGoCalendarRole_ComponentDAndTViewer = @"ComponentDAndTViewer";
 NSString *SOGoCalendarRole_ComponentModifier = @"ComponentModifier";
 NSString *SOGoCalendarRole_ComponentResponder = @"ComponentResponder";
 
+NSString *SOGoMailRole_SeenKeeper = @"MailSeenKeeper";
+NSString *SOGoMailRole_Writer = @"MailWriter";
+NSString *SOGoMailRole_Poster = @"MailPoster";
+NSString *SOGoMailRole_Expunger = @"MailExpunger";
+NSString *SOGoMailRole_Administrator = @"MailAdministrator";
+NSString *SOGoMailRole_MessageEraser = @"MailMessageEraser";
+
 /* permissions */
 NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in
                                               the WebDAV acls spec, which is
@@ -83,3 +95,4 @@ NSString *SOGoCalendarPerm_ViewAllComponent = @"ViewAllComponent";
 NSString *SOGoCalendarPerm_ViewDAndT = @"ViewDAndT";
 NSString *SOGoCalendarPerm_ModifyComponent = @"ModifyComponent";
 NSString *SOGoCalendarPerm_RespondToComponent = @"RespondToComponent";
+
index e4d0b1d35a1faea1f3a9b1526d16a683498c5091..f8104ceedb56dcaacd1e7564b8c83cfeca35e196 100644 (file)
 {
   BOOL prepared;
   BOOL publishInFreeBusy;
-  NSArray *acls;
+  NSArray *aclUsers;
   NSArray *savedUIDs;
   NSMutableArray *users;
   NSString *currentUser;
+  NSString *defaultUserID;
 }
 
 - (NSArray *) aclsForObject;
index e0328ace9530c3722d81972f65e8ef6522a3da6c..e6dccdfe06225e0c3ba883ad5d68560925cdb1e2 100644 (file)
@@ -29,6 +29,7 @@
 #import <SoObjects/SOGo/LDAPUserManager.h>
 #import <SoObjects/SOGo/SOGoContentObject.h>
 #import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/NSArray+Utilities.h>
 
 #import "UIxAclEditor.h"
 
 {
   if ((self = [super init]))
     {
-      acls = nil;
+      aclUsers = nil;
       prepared = NO;
       publishInFreeBusy = NO;
       users = [NSMutableArray new];
       currentUser = nil;
+      defaultUserID = nil;
       savedUIDs = nil;
     }
 
   [savedUIDs release];
   [users release];
   [currentUser release];
+  [defaultUserID release];
   [super dealloc];
 }
 
 - (NSArray *) aclsForObject
 {
-  if (!acls)
-    acls = [[self clientObject] acls];
+  if (!aclUsers)
+    aclUsers = [[self clientObject] aclUsers];
 
-  return acls;
+  return aclUsers;
 }
 
 - (NSString *) _displayNameForUID: (NSString *) uid
 
 - (NSString *) defaultUserID
 {
-  return SOGoDefaultUserID;
+  if (!defaultUserID)
+    ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
+
+  return defaultUserID;
 }
 
 - (void) _prepareUsers
 {
   NSEnumerator *aclsEnum;
-  NSDictionary *currentAcl;
   NSString *currentUID, *ownerLogin;
 
   ownerLogin = [[self clientObject] ownerInContext: context];
+  if (!defaultUserID)
+    ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
 
   aclsEnum = [[self aclsForObject] objectEnumerator];
-  currentAcl = [aclsEnum nextObject];
-  while (currentAcl)
+  currentUID = [aclsEnum nextObject];
+  while (currentUID)
     {
-      currentUID = [currentAcl objectForKey: @"c_uid"];
       if (!([currentUID isEqualToString: ownerLogin]
-           || [currentUID isEqualToString: SOGoDefaultUserID]
-           || [users containsObject: currentUID]))
-         [users addObject: currentUID];
-      currentAcl = [aclsEnum nextObject];
-
-      prepared = YES;
+           || [currentUID isEqualToString: defaultUserID]))
+       [users addObjectUniquely: currentUID];
+      currentUID = [aclsEnum nextObject];
     }
+
+  prepared = YES;
 }
 
 - (NSArray *) usersForObject
index 35cfe15680959a9a526b5954083999dc8b0cb66f..0bef18e5776986f5f10bf424b46cc7c9cb2a67fa 100644 (file)
@@ -34,6 +34,7 @@
 {
   NSMutableArray *userRights;
   NSString *uid;
+  NSString *defaultUserID;
 }
 
 - (NSString *) userDisplayName;
index 8ec44dd463ccbcd140e8f3bd598badfd8563c3bf..ad674f63ec1f010ba990070f9f6a6b2919607ccc 100644 (file)
@@ -25,6 +25,7 @@
 #import <NGObjWeb/WORequest.h>
 #import <SoObjects/SOGo/LDAPUserManager.h>
 #import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/SOGoObject.h>
 
 #import "UIxUserRightsEditor.h"
 
@@ -36,6 +37,7 @@
     {
       uid = nil;
       userRights = [NSMutableArray new];
+      defaultUserID = nil;
     }
 
   return self;
@@ -45,6 +47,7 @@
 {
   [uid release];
   [userRights release];
+  [defaultUserID release];
   [super dealloc];
 }
 
 
 - (BOOL) userIsDefaultUser
 {
-  return [uid isEqualToString: SOGoDefaultUserID];
+  if (!defaultUserID)
+    ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
+
+  return [uid isEqualToString: defaultUserID];
 }
 
 - (NSString *) userDisplayName
   NSString *newUID;
   LDAPUserManager *um;
   SOGoObject *clientObject;
-  unsigned int count;
 
   response = NO;
 
   newUID = [[context request] formValueForKey: @"uid"];
   if ([newUID length] > 0)
     {
+      if (!defaultUserID)
+       ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
+
       um = [LDAPUserManager sharedUserManager];
-      if ([newUID isEqualToString: SOGoDefaultUserID]
+      if ([newUID isEqualToString: defaultUserID]
          || [[um getEmailForUID: newUID] length] > 0)
        {
          ASSIGN (uid, newUID);
          clientObject = [self clientObject];
          [userRights addObjectsFromArray: [clientObject aclsForUser: uid]];
-         count = [userRights count];
-         if (!count || (count == 1 && [[userRights objectAtIndex: 0]
-                                        isEqualToString: SOGoRole_None]))
-           [userRights setArray: [clientObject defaultAclRoles]];
 
          response = YES;
        }
index cca322a0baec29402d194aa8f7435bd3e1bce279..16704ace63416d7043c24c7ffe19bdd4ce8f1f70 100644 (file)
@@ -43,7 +43,7 @@
 "New Card" = "New Card";
 "New List" = "New List";
 "Modify" = "Modify";
-"Access Rights..." = "Access Rights...";
+"Sharing..." = "Sharing...";
 "Write" = "Write";
 "Delete" = "Delete";
 "Instant Message" = "Instant Message";
index aaf6e207537368c02b5e57d2b5b6028186d9aeb7..0d73332edea04ac72b8b3d1d86faf727958a9ed3 100644 (file)
@@ -50,7 +50,7 @@
 "New Card" = "Nouvelle fiche";
 "New List" = "Nouvelle liste";
 "Modify" = "Modifier";
-"Access Rights..." = "Partage...";
+"Sharing..." = "Partage...";
 "Write" = "Écrire";
 "Delete" = "Effacer";
 "Instant Message" = "Message instantané";
index ae25992ef14225083fa0275f911e01c489a7463b..e6d7e66a200974ccad0df9416a1a387e377bb85f 100644 (file)
@@ -39,9 +39,7 @@
 - (NSString *) flatContentAsString
 {
   NSMutableString *content;
-  NSString *superContent, *urlText, *newUrlText;
-  NSRange httpRange, rest, currentURL;
-  unsigned int length;
+  NSString *superContent;
 
   content = [NSMutableString string];
   superContent = [[super flatContentAsString] stringByEscapingHTMLString];
index 49ea90505839f6bd4e5fe226157b1aea614ddf92..bbf54acbd6757ea6d40a664cd378ae0c8585b074 100644 (file)
 "Account: " = "Account: ";
 "Shared Account: " = "Shared Account: ";
 
+/* acls */
+"Default Roles" = "Default Roles";
+
+"List and see this folder" = "List and see this folder";
+"Read mails from this folder" = "Read mails from this folder";
+"Mark mails read and unread" = "Mark mails read and unread";
+"Modify the flags of the mails in this folder" = "Modify the flags of the mails in this folder";
+"Insert, copy and move mails into this folder" = "Insert, copy and move mails into this folder";
+"Post mails" = "Post mails";
+"Add subfolders to this folder" = "Add subfolders to this folder";
+"Remove this folder" = "Remove this folder";
+"Erase mails from this folder" = "Erase mails from this folder";
+"Expunge this folder" = "Expunge this folder";
+"Modify the acl of this folder" = "Modify the acl of this folder";
+
 /* Mail edition */
 
 "From"          = "From";
index 6ba4a8d3e139c286d0233ee0b69e707b192de445..f3ad2063a16450260213240660b57f210b62103e 100644 (file)
 "Account: " = "Compte : ";
 "Shared Account: " = "Compte Partagé ";
 
+/* acls */
+"Default Roles" = "Rôles par défaut";
+
+"List and see this folder" = "Lister et voir ce dossier";
+"Read mails from this folder" = "Lire les messages de ce dossier";
+"Mark mails read and unread" = "Marquer les messages comme lus ou non-lus";
+"Modify the flags of the mails in this folder" = "Modifier les indicateurs sur les messages";
+"Insert, copy and move mails into this folder" = "Insérer, copier et déplacer des messages dans ce dossier";
+"Post mails" = "Poster des messages";
+"Add subfolders to this folder" = "Ajouter des sous-dossiers Ã  ce dossier";
+"Remove this folder" = "Effacer ce dossier";
+"Erase mails from this folder" = "Effacer des messages de ce dossier";
+"Expunge this folder" = "Compacter ce dossier";
+"Modify the acl of this folder" = "Administrer les droits sur ce dossier";
+
 /* Mail edition */
 
 "From"          = "De";
 "New Folder..." = "Nouveau dossier...";
 "Compact This Folder" = "Compacter ce dossier";
 "Search Messages..." = "Rechercher dans les messages...";
-"Properties..." = "Propriétés";
+"Sharing..." = "Partage...";
 "New Subfolder..." = "Nouveau sous-dossier...";
 "Rename Folder..." = "Renommer le dossier...";
 "Delete Folder" = "Supprimer le dossier...";
index 8b3f2108daa1151605d98dc62fbffb3bf0572bc4..b8e7a4b8be1f9d5535bfb7dc0ce48071e277aeef 100644 (file)
@@ -39,7 +39,7 @@ MailerUI_OBJC_FILES += \
        \
        UIxFilterList.m                 \
        \
-       UIxMailFolderACLEditor.m
+       UIxMailUserRightsEditor.m
 #      UIxSieveEditor.m
 
 MailerUI_RESOURCE_FILES += \
diff --git a/UI/MailerUI/UIxMailFolderACLEditor.m b/UI/MailerUI/UIxMailFolderACLEditor.m
deleted file mode 100644 (file)
index 9606edb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-  Copyright (C) 2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo 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 2, or (at your option) any
-  later version.
-
-  OGo 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 Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include <SOGoUI/UIxComponent.h>
-
-// TODO: implement
-
-/*
-  UIxMailFolderACLEditor
-  
-  A component to edit IMAP4 ACLs on folders. It works on SOGoMailFolder
-  objects.
-*/
-
-@interface UIxMailFolderACLEditor : UIxComponent
-{
-}
-
-@end
-
-#include "common.h"
-
-@implementation UIxMailFolderACLEditor
-@end /* UIxMailFolderACLEditor */
diff --git a/UI/MailerUI/UIxMailUserRightsEditor.h b/UI/MailerUI/UIxMailUserRightsEditor.h
new file mode 100644 (file)
index 0000000..289c95c
--- /dev/null
@@ -0,0 +1,58 @@
+/* UIxMailUserRightsEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@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 UIXMAILUSERRIGHTSEDITOR_H
+#define UIXMAILUSERRIGHTSEDITOR_H
+
+#import <UI/Common/UIxUserRightsEditor.h>
+
+@interface UIxMailUserRightsEditor : UIxUserRightsEditor
+
+- (void) setUserCanReadMails: (BOOL) userCanReadMails;
+- (BOOL) userCanReadMails;
+
+- (void) setUserCanWriteMails: (BOOL) userCanWriteMails;
+- (BOOL) userCanWriteMails;
+
+- (void) setUserCanInsertMails: (BOOL) userCanInsertMails;
+- (BOOL) userCanInsertMails;
+
+- (void) setUserCanMarkMailsRead: (BOOL) userCanMarkMailsRead;
+- (BOOL) userCanMarkMailsRead;
+
+- (void) setUserCanEraseMails: (BOOL) userCanEraseMails;
+- (BOOL) userCanEraseMails;
+
+- (void) setUserCanCreateSubfolders: (BOOL) userCanCreateSubfolders;
+- (BOOL) userCanCreateSubfolders;
+
+- (void) setUserCanPostMails: (BOOL) userCanPostMails;
+- (BOOL) userCanPostMails;
+
+- (void) setUserIsAdministrator: (BOOL) userIsAdministrator;
+- (BOOL) userIsAdministrator;
+
+- (void) updateRights;
+
+@end
+
+#endif /* UIXMAILUSERRIGHTSEDITOR_H */
diff --git a/UI/MailerUI/UIxMailUserRightsEditor.m b/UI/MailerUI/UIxMailUserRightsEditor.m
new file mode 100644 (file)
index 0000000..2478b5c
--- /dev/null
@@ -0,0 +1,238 @@
+/* UIxMailUserRightsEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@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/NSArray.h>
+#import <Foundation/NSEnumerator.h>
+#import <NGObjWeb/WORequest.h>
+#import <SoObjects/SOGo/SOGoPermissions.h>
+
+#import "UIxMailUserRightsEditor.h"
+
+@implementation UIxMailUserRightsEditor
+
+- (void) setUserCanSeeFolder: (BOOL) userCanSeeFolder
+{
+  if (userCanSeeFolder)
+    [self appendRight: SOGoRole_ObjectViewer];
+  else
+    [self removeRight: SOGoRole_ObjectViewer];
+}
+
+- (BOOL) userCanSeeFolder
+{
+  return [userRights containsObject: SOGoRole_ObjectViewer];
+}
+
+- (void) setUserCanReadMails: (BOOL) userCanReadMails
+{
+  if (userCanReadMails)
+    [self appendRight: SOGoRole_ObjectReader];
+  else
+    [self removeRight: SOGoRole_ObjectReader];
+}
+
+- (BOOL) userCanReadMails
+{
+  return [userRights containsObject: SOGoRole_ObjectReader];
+}
+
+- (void) setUserCanMarkMailsRead: (BOOL) userCanMarkMailsRead
+{
+  if (userCanMarkMailsRead)
+    [self appendRight: SOGoMailRole_SeenKeeper];
+  else
+    [self removeRight: SOGoMailRole_SeenKeeper];
+}
+
+- (BOOL) userCanMarkMailsRead
+{
+  return [userRights containsObject: SOGoMailRole_SeenKeeper];
+}
+
+- (void) setUserCanWriteMails: (BOOL) userCanWriteMails
+{
+  if (userCanWriteMails)
+    [self appendRight: SOGoMailRole_Writer];
+  else
+    [self removeRight: SOGoMailRole_Writer];
+}
+
+- (BOOL) userCanWriteMails
+{
+  return [userRights containsObject: SOGoMailRole_Writer];
+}
+
+- (void) setUserCanInsertMails: (BOOL) userCanInsertMails
+{
+  if (userCanInsertMails)
+    [self appendRight: SOGoRole_ObjectCreator];
+  else
+    [self removeRight: SOGoRole_ObjectCreator];
+}
+
+- (BOOL) userCanInsertMails
+{
+  return [userRights containsObject: SOGoRole_ObjectCreator];
+}
+
+- (void) setUserCanPostMails: (BOOL) userCanPostMails
+{
+  if (userCanPostMails)
+    [self appendRight: SOGoMailRole_Poster];
+  else
+    [self removeRight: SOGoMailRole_Poster];
+}
+
+- (BOOL) userCanPostMails
+{
+  return [userRights containsObject: SOGoMailRole_Poster];
+}
+
+- (void) setUserCanCreateSubfolders: (BOOL) userCanCreateSubfolders
+{
+  if (userCanCreateSubfolders)
+    [self appendRight: SOGoRole_FolderCreator];
+  else
+    [self removeRight: SOGoRole_FolderCreator];
+}
+
+- (BOOL) userCanCreateSubfolders
+{
+  return [userRights containsObject: SOGoRole_FolderCreator];
+}
+
+- (void) setUserCanRemoveFolder: (BOOL) userCanRemoveFolder
+{
+  if (userCanRemoveFolder)
+    [self appendRight: SOGoRole_ObjectEraser];
+  else
+    [self removeRight: SOGoRole_ObjectEraser];
+}
+
+- (BOOL) userCanRemoveFolder
+{
+  return [userRights containsObject: SOGoRole_ObjectEraser];
+}
+
+- (void) setUserCanEraseMails: (BOOL) userCanEraseMails
+{
+  if (userCanEraseMails)
+    [self appendRight: SOGoMailRole_MessageEraser];
+  else
+    [self removeRight: SOGoMailRole_MessageEraser];
+}
+
+- (BOOL) userCanEraseMails
+{
+  return [userRights containsObject: SOGoMailRole_MessageEraser];
+}
+
+- (void) setUserCanExpungeFolder: (BOOL) userCanExpungeFolder
+{
+  if (userCanExpungeFolder)
+    [self appendRight: SOGoMailRole_Expunger];
+  else
+    [self removeRight: SOGoMailRole_Expunger];
+}
+
+- (BOOL) userCanExpungeFolder
+{
+  return [userRights containsObject: SOGoMailRole_Expunger];
+}
+
+- (void) setUserIsAdministrator: (BOOL) userIsAdministrator
+{
+  if (userIsAdministrator)
+    [self appendRight: SOGoMailRole_Administrator];
+  else
+    [self removeRight: SOGoMailRole_Administrator];
+}
+
+- (BOOL) userIsAdministrator
+{
+  return [userRights containsObject: SOGoMailRole_Administrator];
+}
+
+- (void) updateRights
+{
+  WORequest *request;
+
+  request = [context request];
+
+  if ([[request formValueForKey: SOGoRole_ObjectViewer] length] > 0)
+    [self appendRight: SOGoRole_ObjectViewer];
+  else
+    [self removeRight: SOGoRole_ObjectViewer];
+
+  if ([[request formValueForKey: SOGoRole_ObjectReader] length] > 0)
+    [self appendRight: SOGoRole_ObjectReader];
+  else
+    [self removeRight: SOGoRole_ObjectReader];
+
+  if ([[request formValueForKey: SOGoMailRole_SeenKeeper] length] > 0)
+    [self appendRight: SOGoMailRole_SeenKeeper];
+  else
+    [self removeRight: SOGoMailRole_SeenKeeper];
+
+  if ([[request formValueForKey: SOGoMailRole_Writer] length] > 0)
+    [self appendRight: SOGoMailRole_Writer];
+  else
+    [self removeRight: SOGoMailRole_Writer];
+
+  if ([[request formValueForKey: SOGoRole_ObjectCreator] length] > 0)
+    [self appendRight: SOGoRole_ObjectCreator];
+  else
+    [self removeRight: SOGoRole_ObjectCreator];
+
+  if ([[request formValueForKey: SOGoMailRole_Poster] length] > 0)
+    [self appendRight: SOGoMailRole_Poster];
+  else
+    [self removeRight: SOGoMailRole_Poster];
+
+  if ([[request formValueForKey: SOGoRole_FolderCreator] length] > 0)
+    [self appendRight: SOGoRole_FolderCreator];
+  else
+    [self removeRight: SOGoRole_FolderCreator];
+
+  if ([[request formValueForKey: SOGoRole_ObjectEraser] length] > 0)
+    [self appendRight: SOGoRole_ObjectEraser];
+  else
+    [self removeRight: SOGoRole_ObjectEraser];
+
+  if ([[request formValueForKey: SOGoMailRole_MessageEraser] length] > 0)
+    [self appendRight: SOGoMailRole_MessageEraser];
+  else
+    [self removeRight: SOGoMailRole_MessageEraser];
+
+  if ([[request formValueForKey: SOGoMailRole_Expunger] length] > 0)
+    [self appendRight: SOGoMailRole_Expunger];
+  else
+    [self removeRight: SOGoMailRole_Expunger];
+
+  if ([[request formValueForKey: SOGoMailRole_Administrator] length] > 0)
+    [self appendRight: SOGoMailRole_Administrator];
+  else
+    [self removeRight: SOGoMailRole_Administrator];
+}
+
+@end
index 0979d877f10b21d2eb01cb0dcaec2ac2ab945528..ea820f5b6cfe8d3a71f802bee0c78f27db45cf51 100644 (file)
@@ -1,5 +1,5 @@
 { /* -*-javascript-*- */
-  requires = ( MAIN, CommonUI, Mailer ); /* , Sieve */
+  requires = ( MAIN, MainUI, CommonUI, Mailer ); /* , Sieve */
 
   publicResources = (
     "uix.css",
           pageName    = "UIxMailListView";
           actionName  = "deleteFolder";
         };
-        editACL = {
-          protectedBy = "View";
-          pageName    = "UIxMailFolderACLEditor";
-        };
         compose = {
           protectedBy = "View";
           actionClass = "UIxMailEditorAction";
           actionName  = "compose";
         };
+       userRights = {
+          protectedBy = "ReadAcls";
+          pageName    = "UIxMailUserRightsEditor";
+       };
+       saveUserRights = {
+          protectedBy = "SaveAcls";
+          pageName    = "UIxMailUserRightsEditor";
+          actionName  = "saveUserRights";
+       };
       };
     };
 
index 050f12defa6d0862db02ff97a7975b84cc5e9f66..05d991c9a712bd6ef934dff4c2119c702a7fe151 100644 (file)
@@ -70,7 +70,7 @@
 
 "New Calendar..." = "New Calendar...";
 "Delete Calendar" = "Delete Calendar";
-"Access Rights..." = "Access Rights...";
+"Sharing..." = "Sharing...";
 "Export Calendar..." = "Export Calendar...";
 "Publish Calendar..." = "Publish Calendar...";
 "Reload Remote Calendars" = "Reload Remote Calendars";
index 46b02d33ac7b2d3005f54e8454263856be776135..44e9be99e360ea480663c90a7178e6a5180c1638 100644 (file)
@@ -71,7 +71,7 @@
 
 "New Calendar..." = "Nouvel agenda...";
 "Delete Calendar" = "Effacer l'agenda";
-"Access Rights..." = "Partage";
+"Sharing..." = "Partage...";
 "Export Calendar..." = "Exporter l'agenda...";
 "Publish Calendar..." = "Publier l'agenda...";
 "Reload Remote Calendars" = "Recharger les agendas distants";
index 916ce36c408992c3529cdf5d5e82a4a76f0e6901..8e92f86d5de3d26df9648c6d48c5f31e1d697c2c 100644 (file)
@@ -7,9 +7,8 @@
     >
     <div class="menu" id="searchMenu">
       <ul id="searchOptions">
-        <li id="name_or_address"
-          onmousedown="return false;"
-          onmouseup="setSearchCriteria(event);"><var:string label:value="Name or Email"/></li>
+        <li id="name_or_address"><var:string
+           label:value="Name or Email"/></li>
       </ul>
     </div>
 
index f53445b0df691f21bb0fbf334ca8a18f67868e50..8a2d86556577b73f0731ad40b035290e666cb8ba 100644 (file)
     <div class="menu" id="contactFoldersMenu">
       <ul>
        <li><var:string label:value="Modify" /></li>
-       <li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
-       <li class="separator"></li>
-       <li class="disabled"><var:string label:value="New Card" /></li>
-       <li class="disabled"><var:string label:value="New List" /></li>
-       <li class="separator"></li>
-       <li class="disabled"><var:string label:value="Delete" /></li>
+       <li><!-- separator --></li>
+       <li><var:string label:value="New Card" /></li>
+       <li><var:string label:value="New List" /></li>
+       <li><!-- separator --></li>
+       <li><var:string label:value="Delete" /></li>
+       <li><!-- separator --></li>
+       <li><var:string label:value="Sharing..." /></li>
       </ul>
     </div>
 
     <div class="menu" id="contactMenu">
       <ul>
-       <li id="modifyContactMenuEntry" onmouseup="return onMenuEditContact(event, this);"><var:string label:value="Modify" /></li>
-       <li class="separator"></li>
-       <li id="writeToContactMenuEntry" onmouseup="return onMenuWriteToContact(event, this);"><var:string label:value="Write" /></li>
-       <li class="disabled" id="imContactMenuEntry"><var:string label:value="Instant Message" /></li>
-       <li class="separator"></li>
-       <li id="deleteContactMenuEntry" onmouseup="return onMenuDeleteContact(event, this);"><var:string label:value="Delete" /></li>
+       <li><var:string label:value="Modify" /></li>
+       <li><!-- separator --></li>
+       <li><var:string label:value="Write" /></li>
+       <li><var:string label:value="Instant Message" /></li>
+       <li><!-- separator --></li>
+       <li><var:string label:value="Delete" /></li>
       </ul>
     </div>
 
diff --git a/UI/Templates/MailerUI/UIxMailFolderACLEditor.wox b/UI/Templates/MailerUI/UIxMailFolderACLEditor.wox
deleted file mode 100644 (file)
index 421c98c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-  <var:component
-    xmlns="http://www.w3.org/1999/xhtml"
-    xmlns:var="http://www.skyrix.com/od/binding"
-    xmlns:const="http://www.skyrix.com/od/constant"
-    xmlns:uix="OGo:uix"
-    xmlns:rsrc="OGo:url"
-    xmlns:label="OGo:label"
-    className="UIxPageFrame"
-    title="panelTitle"
-    const:popup="YES">
-    TODO: IMAP4 ACL editor
-  </var:component>
index 1e7be00aebe69aa657376946ee48bffa011d311e..e5e57d9dc36141447e4d94eaed31915a8b2b4ebc 100644 (file)
     >
     <div class="menu" id="accountIconMenu">
       <ul>
-        <li class="disabled"><var:string label:value="Subscribe..." /></li>
-        <li class="disabled"><var:string label:value="Get Messages for Account" /></li>
-        <li class="disabled"><var:string label:value="New Folder..." /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Search Messages..." /></li>
-        <li class="disabled"><var:string label:value="Properties..." /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li><var:string label:value="Get Messages for Account" /></li>
+        <li><var:string label:value="New Folder..." /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Properties..." /></li>
       </ul>
     </div>
 
     <div class="menu" id="inboxIconMenu">
       <ul>
-        <li class="disabled"><var:string label:value="Open in New Mail Window" /></li>
-        <li class="disabled"><var:string label:value="Copy Folder Location" /></li>
-        <li class="disabled"><var:string label:value="Subscribe..." /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Mark Folder Read..." /></li>
-        <li class="disabled"><var:string label:value="New Folder..." /></li>
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Folder..." /></li>
         <li><var:string label:value="Compact This Folder" /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Search Messages..." /></li>
-        <li class="disabled"><var:string label:value="Properties..." /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Sharing..." /></li>
       </ul>
     </div>
       
     <div class="menu" id="trashIconMenu">
       <ul>
-        <li class="disabled"><var:string label:value="Open in New Mail Window" /></li>
-        <li class="disabled"><var:string label:value="Copy Folder Location" /></li>
-        <li class="disabled"><var:string label:value="Subscribe..." /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Mark Folder Read..." /></li>
-        <li class="disabled"><var:string label:value="New Subfolder..." /></li>
-        <li class="disabled"><var:string label:value="Compact This Folder" /></li>
-        <li class="disabled"><var:string label:value="Empty Trash" /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Search Messages..." /></li>
-        <li class="disabled"><var:string label:value="Properties..." /></li>
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Subfolder..." /></li>
+        <li><var:string label:value="Compact This Folder" /></li>
+        <li><var:string label:value="Empty Trash" /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Sharing..." /></li>
       </ul>
     </div>
 
     <div class="menu" id="mailboxIconMenu">
       <ul>
-        <li class="disabled"><var:string label:value="Open in New Mail Window" /></li>
-        <li class="disabled"><var:string label:value="Copy Folder Location" /></li>
-        <li class="disabled"><var:string label:value="Subscribe..." /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Mark Folder Read..." /></li>
-        <li class="disabled"><var:string label:value="New Subfolder..." /></li>
-        <li class="disabled"><var:string label:value="Rename Folder..." /></li>
-        <li class="disabled"><var:string label:value="Compact This Folder" /></li>
-        <li class="disabled"><var:string label:value="Delete Folder" /></li>
-        <li class="separator"></li>
-        <li class="disabled"><var:string label:value="Search Messages..." /></li>
-       <li class="disabled"><var:string label:value="Properties..." /></li>
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Subfolder..." /></li>
+        <li><var:string label:value="Rename Folder..." /></li>
+        <li><var:string label:value="Compact This Folder" /></li>
+        <li><var:string label:value="Delete Folder" /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Search Messages..." /></li>
+       <li><var:string label:value="Sharing..." /></li>
       </ul>
     </div>
     
     <div class="menu" id="addressMenu">
       <ul>
-        <li id="add_to_addressbook"
-          onmouseup="newContactFromEmail(this);"><var:string label:value="Add to Address Book..."/></li>
-        <li id="compose_mailto"
-          onmouseup="newEmailTo(this);"><var:string label:value="Compose Mail To"/></li>
-        <li id="create_filter"
-          onmouseup="onMenuEntryClick(this, event);"><var:string label:value="Create Filter From Message..."/></li>
+        <li id="add_to_addressbook"><var:string label:value="Add to Address Book..."/></li>
+        <li id="compose_mailto"><var:string label:value="Compose Mail To"/></li>
+        <li id="create_filter"><var:string label:value="Create Filter From Message..."/></li>
       </ul>
     </div>
 
     <div class="menu" id="messageListMenu">
       <ul>
-        <li
-          onmouseup="onMenuOpenMessage(event);"><var:string label:value="Open Message In New Window"/></li>
-        <li class="separator"></li>
-        <li
-          onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
-        <li
-          onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
-        <li
-          onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
-        <li class="disabled"
-          onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
-        <li class="separator"></li>
-        <li
-          class="disabled submenu"
-          mailboxaction="move"
-          submenu="mailboxes-menu"
-          onmouseoverx="dropDownSubmenu(event);"><var:string label:value="Move To"/></li>
-        <li
-          class="disabled submenu"
-          mailboxaction="copy"
-          submenu="mailboxes-menu"
-          onmouseoverx="dropDownSubmenu(event);"><var:string label:value="Copy To"/></li>
-        <li
-          class="disabled submenu"
-          submenu="label-menu"
-          onmouseoverx="dropDownSubmenu(event);"><var:string label:value="Label"/></li>
-        <li
-          class="disabled submenu"
-          submenu="mark-menu"
-          onmouseoverx="dropDownSubmenu(event);"><var:string label:value="Mark"/></li>
-        <li class="separator"></li>
-        <li class="disabled"
-          onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
-        <li class="disabled"
-          onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
-        <li class="disabled"
-          onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
-        <li
-          onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
+        <li><var:string label:value="Open Message In New Window"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Reply to Sender Only"/></li>
+        <li><var:string label:value="Reply to All"/></li>
+        <li><var:string label:value="Forward"/></li>
+        <li><var:string label:value="Edit As New..."/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Move To"/></li>
+        <li><var:string label:value="Copy To"/></li>
+        <li><var:string label:value="Label"/></li>
+        <li><var:string label:value="Mark"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Save As..."/></li>
+        <li><var:string label:value="Print Preview"/></li>
+        <li><var:string label:value="Print..."/></li>
+        <li><var:string label:value="Delete Message"/></li>
       </ul>
     </div>
 
     <div class="menu" id="messageContentMenu">
       <ul>
-        <li
-          onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
-        <li
-          onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
-        <li
-          onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
-        <li
-          onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
-        <li
-          class="submenu"
-          mailboxaction="move"
-          submenu="mailboxes-menu"
-          onmouseover="dropDownSubmenu(event);"><var:string label:value="Move To"/></li>
-        <li
-          class="submenu"
-          mailboxaction="copy"
-          submenu="mailboxes-menu"
-          onmouseover="dropDownSubmenu(event);"><var:string label:value="Copy To"/></li>
-        <li class="separator"></li>
-        <li
-          class="submenu"
-          submenu="label-menu"
-          onmouseover="dropDownSubmenu(event);"><var:string label:value="Label"/></li>
-        <li
-          class="submenu"
-          submenu="mark-menu"
-          onmouseover="dropDownSubmenu(event);"><var:string label:value="Mark"/></li>
-        <li class="separator"></li>
-        <li
-          onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
-        <li
-          onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
-        <li
-          onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
-        <li
-          onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
+        <li><var:string label:value="Reply to Sender Only"/></li>
+        <li><var:string label:value="Reply to All"/></li>
+        <li><var:string label:value="Forward"/></li>
+        <li><var:string label:value="Edit As New..."/></li>
+        <li><var:string label:value="Move To"/></li>
+        <li><var:string label:value="Copy To"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Label"/></li>
+        <li><var:string label:value="Mark"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Save As..."/></li>
+        <li><var:string label:value="Print Preview"/></li>
+        <li><var:string label:value="Print..."/></li>
+        <li><var:string label:value="Delete Message"/></li>
       </ul>
     </div>
 
     <div class="menu" id="label-menu">
       <ul id="">
-        <li onmouseup="onMenuLabelMessage(event, 'none');"><var:string label:value="None" /></li>
-        <li class="separator"></li>
-        <li onmouseup="onMenuLabelMessage(event, 'important);"><var:string label:value="Important" /></li>
-        <li onmouseup="onMenuLabelMessage(event, 'work');"><var:string label:value="Work" /></li>
-        <li onmouseup="onMenuLabelMessage(event, 'personal');"><var:string label:value="Personal" /></li>
-        <li onmouseup="onMenuLabelMessage(event, 'todo');"><var:string label:value="To Do" /></li>
-        <li onmouseup="onMenuLabelMessage(event, 'later');"><var:string label:value="Later" /></li>
+        <li><var:string label:value="None" /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Important" /></li>
+        <li><var:string label:value="Work" /></li>
+        <li><var:string label:value="Personal" /></li>
+        <li><var:string label:value="To Do" /></li>
+        <li><var:string label:value="Later" /></li>
       </ul>
     </div>
 
 
     <div class="menu" id="mark-menu">
       <ul id="">
-        <li onmouseup="onMenuMarkMessage(event, 'read');"><var:string label:value="As Read" /></li>
-        <li onmouseup="onMenuMarkMessage(event, 'threadread');"><var:string label:value="Thread As Read" /></li>
-        <li onmouseup="onMenuMarkMessage(event, 'readbydate);"><var:string label:value="As Read By Date..." /></li>
-        <li onmouseup="onMenuMarkMessage(event, 'allread);"><var:string label:value="All Read" /></li>
-        <li class="separator"></li>
-        <li onmouseup="onMenuMarkMessage(event, 'flag);"><var:string label:value="Flag" /></li>
-        <li class="separator"></li>
-        <li onmouseup="onMenuMarkMessage(event, 'junk);"><var:string label:value="As Junk" /></li>
-        <li onmouseup="onMenuMarkMessage(event, 'notjunk);"><var:string label:value="As Not Junk" /></li>
-        <li onmouseup="onMenuMarkMessage(event, 'runjunkmailcontrols);"><var:string label:value="Run Junk Mail Controls" /></li>
+        <li><var:string label:value="As Read" /></li>
+        <li><var:string label:value="Thread As Read" /></li>
+        <li><var:string label:value="As Read By Date..." /></li>
+        <li><var:string label:value="All Read" /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Flag" /></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="As Junk" /></li>
+        <li><var:string label:value="As Not Junk" /></li>
+        <li><var:string label:value="Run Junk Mail Controls" /></li>
       </ul>
     </div>
 
diff --git a/UI/Templates/MailerUI/UIxMailUserRightsEditor.wox b/UI/Templates/MailerUI/UIxMailUserRightsEditor.wox
new file mode 100644 (file)
index 0000000..998f5b6
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:var="http://www.skyrix.com/od/binding"
+  xmlns:const="http://www.skyrix.com/od/constant"
+  xmlns:uix="OGo:uix"
+  xmlns:label="OGo:label"
+  xmlns:rsrc="OGo:url"
+  className="UIxPageFrame"
+  title="title"
+  const:toolbar="none"
+  const:popup="YES">
+  <form id="userRightsForm" const:href="saveUserRights">
+    <input type="hidden" name="uid" var:value="uid"/>
+    <div class="title">
+      <var:if condition="userIsDefaultUser">
+       <label><span class="value"><var:string label:value="Default Roles"
+             /></span></label>
+      </var:if><var:if condition="userIsDefaultUser" const:negate="YES">
+       <label><var:string label:value="User rights for:"/><br/>
+         <span class="value"><var:string value="userDisplayName"
+             /></span></label></var:if>
+    </div>
+    <div class="calendarUserRights">
+      <label><input type="checkbox" class="checkBox"
+         const:name="ObjectViewer"
+         var:checked="userCanSeeFolder"/><var:string
+         label:value="List and see this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="ObjectReader"
+         var:checked="userCanReadMails"/><var:string
+         label:value="Read mails from this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailSeenKeeper"
+         var:checked="userCanMarkMailsRead"/><var:string
+         label:value="Mark mails read and unread"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailWriter"
+         var:checked="userCanWriteMails"/><var:string
+         label:value="Modify the flags of the mails in this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="ObjectCreator"
+         var:checked="userCanInsertMails"/><var:string
+         label:value="Insert, copy and move mails into this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailPoster"
+         var:checked="userCanPostMails"/><var:string
+         label:value="Post mails"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="FolderCreator"
+         var:checked="userCanCreateSubfolders"/><var:string
+         label:value="Add subfolders to this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="ObjectEraser"
+         var:checked="userCanRemoveFolder"/><var:string
+         label:value="Remove this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailMessageEraser"
+         var:checked="userCanEraseMails"/><var:string
+         label:value="Erase mails from this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailExpunger"
+         var:checked="userCanExpungeFolder"/><var:string
+         label:value="Expunge this folder"/></label>
+      <br/>
+      <label><input type="checkbox" class="checkBox"
+         const:name="MailAdministrator"
+         var:checked="userIsAdministrator"/><var:string
+         label:value="Modify the acl of this folder"/></label>
+      <br/>
+    </div>
+    <div class="buttons">
+      <input const:name="updateButton" id="updateButton"
+       class="button" type="submit" label:value="Update"/>
+      <input const:name="cancelButton" id="cancelButton"
+       class="button" type="button" label:value="Cancel"/>
+    </div>
+  </form>
+</var:component>
index 44c03cadeb46d2d18298993eb860ae8ddb271018..c0b6f513be6e33649e179f4d5a325e1b15dc3af9 100644 (file)
@@ -7,9 +7,7 @@
     >
     <div class="menu" id="searchMenu">
       <ul id="searchOptions">
-        <li id="name_or_address"
-          onmousedown="return false;"
-          onmouseup="setSearchCriteria(event);"><var:string label:value="Title or Description"/></li>
+        <li><var:string label:value="Title or Description"/></li>
       </ul>
     </div>
 
index 62d0d9c2554ed9d2d02d8c956ab6c45fd84ca422..6c075ace7486656cf5638d7cd9ac7400bfbed994 100644 (file)
     <div class="menu" id="monthListMenu">
       <ul>
         <var:foreach list="monthMenuItems" item="monthMenuItem"
-          ><li
-            onmousedown="return false;"
-            onclick="return onMonthMenuItemClick(this);"
-            var:month="monthMenuItem"
+          ><li var:month="monthMenuItem"
             ><var:string value="monthMenuItemLabel" /></li>
         </var:foreach
           ></ul>
     <div class="menu" id="yearListMenu">
       <ul>
         <var:foreach list="yearMenuItems" item="yearMenuItem"
-          ><li
-            onmousedown="return false;"
-            onclick="return onYearMenuItemClick(this);"
-            ><var:string value="yearMenuItem" /></li>
+          ><li><var:string value="yearMenuItem" /></li>
         </var:foreach
         ></ul>
     </div>
 
     <div class="menu" id="appointmentsListMenu">
       <ul>
-        <li onmouseup="newEvent(this, 'event');"><var:string label:value="New Event..."/></li>
-        <li class="separator"></li>
-        <li onmouseup="newEvent(this, 'task');"><var:string label:value="New Task..."/></li>
-        <li onmouseup="editEvent();"><var:string label:value="Edit Selected Event..."/></li>
-        <li onmouseup="deleteEvent();"><var:string label:value="Delete Selected Event"/></li>
-        <li class="separator"></li>
-        <li onmouseup="onSelectAll();"><var:string label:value="Select All"/></li>
-        <li class="separator"></li>
-        <li onmouseup="onToggleWorkweekDaysOnly();"><var:string label:value="Workweek days only" /></li>
-        <li onmouseup="onToggleTasksInView();"><var:string label:value="Tasks in View"/></li>
+        <li><var:string label:value="New Event..."/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="New Task..."/></li>
+        <li><var:string label:value="Edit Selected Event..."/></li>
+        <li><var:string label:value="Delete Selected Event"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Select All"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Workweek days only"/></li>
+        <li><var:string label:value="Tasks in View"/></li>
       </ul>
     </div>
 
     <div class="menu" id="calendarsMenu">
       <ul>
-        <li class="disabled" id="newCalendarMenuEntry"><var:string label:value="New Calendar..."/></li>
-        <li class="disabled" id="deleteCalendarMenuEntry"><var:string label:value="Delete Calendar"/></li>
-        <li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
-        <li class="separator"></li>
-        <li class="disabled" id="exportCalendarMenuEntry"><var:string label:value="Export Calendar..."/></li>
-        <li class="disabled" id="publishCalendarMenuEntry"><var:string label:value="Publish Calendar..."/></li>
-        <li class="separator"></li>
-        <li class="disabled" id="publishCalendarMenuEntry"><var:string label:value="Reload Remote Calendars"/></li>
-        <li class="separator"></li>
-        <li class="disabled" id="calendarPropertiesMenuEntry"><var:string label:value="Properties"/></li>
+        <li><var:string label:value="New Calendar..."/></li>
+        <li><var:string label:value="Delete Calendar"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Export Calendar..."/></li>
+        <li><var:string label:value="Publish Calendar..."/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Reload Remote Calendars"/></li>
+        <li><!-- separator --></li>
+        <li><var:string label:value="Sharing..." /></li>
       </ul>
     </div>
 
index 58ba94c90077a8bac3a85ade4e051d2e13380f5d..301ef5dcb4f035adbab7db6fc12aff4958f8f350 100644 (file)
@@ -22,8 +22,9 @@
        <label><var:string label:value="Owner:"/><br/>
          <span class="value"><strong><var:string value="ownerName"/></strong></span></label><br/>
       </div>
-      <input id="defaultRolesBtn" type="button"
-       class="button" label:value="Default Roles"/>
+      <var:if condition="clientObject.hasSupportForDefaultRoles"
+       ><input id="defaultRolesBtn" type="button"
+         class="button" label:value="Default Roles"/></var:if>
       <div class="userSelector" id="userRoles">
        <var:if condition="currentUserIsOwner">
          <span id="userSelectorButtons">
index 5e4c664ececd0d69fec3743b47c38c8aefcd5803..3342911333614e540f85e1021711a0f09597d524 100644 (file)
@@ -91,7 +91,7 @@ function contactsListCallback(http) {
 function onContactFoldersContextMenu(event) {
   var menu = $("contactFoldersMenu");
   menu.addEventListener("hideMenu", onContactFoldersContextMenuHide, false);
-  onMenuClick(event, "contactFoldersMenu");
+  popupMenu(event, "contactFoldersMenu", this);
 
   var topNode = $("contactFolders");
   var selectedNodes = topNode.getSelectedRows();
@@ -105,7 +105,7 @@ function onContactFoldersContextMenu(event) {
 function onContactContextMenu(event, element) {
   var menu = $("contactMenu");
   menu.addEventListener("hideMenu", onContactContextMenuHide, false);
-  onMenuClick(event, "contactMenu");
+  popupMenu(event, "contactMenu", element);
 
   var topNode = $("contactsList");
   var selectedNodes = topNode.getSelectedRows();
@@ -235,31 +235,23 @@ function onContactRowDblClick(event, node) {
   return false;
 }
 
-function onMenuEditContact(event, node) {
-  var node = getParentMenu(node).menuTarget.parentNode;
-  var contactId = node.getAttribute('id');
+function onMenuEditContact(event) {
+  var contactId = document.menuTarget.getAttribute('id');
 
   openContactWindow(null,
                     URLForFolderID(currentContactFolder)
                     + "/" + contactId + "/edit");
-
-  return false;
 }
 
-function onMenuWriteToContact(event, node) {
-  var node = getParentMenu(node).menuTarget.parentNode;
-  var contactId = node.getAttribute('id');
-
-  openMailComposeWindow(ApplicationBaseURL + currentContactFolder
-                        + "/" + contactId + "/write");
+function onMenuWriteToContact(event) {
+   var contactId = document.menuTarget.getAttribute('id');
 
-  return false;
+   openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+                        + "/" + contactId + "/write");
 }
 
-function onMenuDeleteContact(event, node) {
-  uixDeleteSelectedContacts(node);
-
-  return false;
+function onMenuDeleteContact(event) {
+  uixDeleteSelectedContacts(this);
 }
 
 function onToolbarEditSelectedContacts(event) {
@@ -611,21 +603,27 @@ function configureContactFolders() {
   }
 }
 
-function onAccessRightsMenuEntryMouseUp(event) {
-  var folders = $("contactFolders");
-  var selected = folders.getSelectedNodes()[0];
-  var title = this.innerHTML;
-  var url = URLForFolderID(selected.getAttribute("id"))
+function onMenuSharing(event) {
+   var folders = $("contactFolders");
+   var selected = folders.getSelectedNodes()[0];
+   var title = this.innerHTML;
+   var url = URLForFolderID(selected.getAttribute("id"));
 
-  openAclWindow(url + "/acls", title);
+   openAclWindow(url + "/acls", title);
 }
 
 function initializeMenus() {
-  var menus = new Array("contactFoldersMenu", "contactMenu", "searchMenu");
-  initMenusNamed(menus);
-
-  var menuEntry = $("accessRightsMenuEntry");
-  menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
+   menus["menuIds"] = new Array("contactFoldersMenu", "contactMenu",
+                               "searchMenu");
+   menus["contactFoldersMenu"] = new Array(null, "-", null,
+                                          null, "-", null, "-",
+                                          onMenuSharing);
+   menus["contactMenu"] = new Array(onMenuEditContact, "-",
+                                   onMenuWriteToContact, null, "-",
+                                   onMenuDeleteContact);
+   menus["searchMenu"] = new Array(setSearchCriteria);
+
+   initMenus();
 }
 
 function configureSearchField() {
index 6168bfb9e77f21297f4937f23c8b8ca678b6bd9f..44e876b99fb15928a337e73eb872340203014ecc 100644 (file)
@@ -216,7 +216,7 @@ HTMLElement.prototype.onContextMenu = function(event) {
 
 HTMLElement.prototype.attachMenu = function(menuName) {
   this.sogoContextMenu = $(menuName);
-  this.addEventListener("contextmenu", this.onContextMenu, true);
+  Event.observe(this, "contextmenu", this.onContextMenu);
 }
 
 HTMLElement.prototype.select = function() {
index 20739d874a14bef6eda291ba80600baf5210518a..075d020cec8be4a3b18e5c53f7b736881cf6c441 100644 (file)
@@ -4,228 +4,240 @@ var currentMessages = new Array();
 var maxCachedMessages = 20;
 var cachedMessages = new Array();
 var currentMailbox = '';
+
+var usersRightsWindowHeight = 320;
+var usersRightsWindowWidth = 400;
+
 /* mail list */
 
 function openMessageWindow(msguid, url) {
-  var wId = '';
-  if (msguid) {
-    wId += "SOGo_msg_" + msguid;
-    markMailReadInWindow(window, msguid);
-  }
-  var msgWin = window.open(url, wId,
-                          "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
-                           + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  if (msguid) {
-    msgWin.messageId = msguid;
-    msgWin.messageURL = ApplicationBaseURL + currentMailbox + "/" + msguid;
-  }
-  msgWin.focus();
-
-  return false;
+   var wId = '';
+   if (msguid) {
+      wId += "SOGo_msg_" + msguid;
+      markMailReadInWindow(window, msguid);
+   }
+   var msgWin = window.open(url, wId,
+                           "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
+                           + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+   if (msguid) {
+      msgWin.messageId = msguid;
+      msgWin.messageURL = ApplicationBaseURL + currentMailbox + "/" + msguid;
+   }
+   msgWin.focus();
+
+   return false;
 }
 
 function onMessageDoubleClick(event) {
-  resetSelection(window);
-  var msguid = this.parentNode.id.substr(4);
-  
-  return openMessageWindow(msguid,
-                           ApplicationBaseURL + currentMailbox + "/"
-                           + msguid + "/popupview");
+   resetSelection(window);
+   var msguid = this.parentNode.id.substr(4);
+   
+   return openMessageWindow(msguid,
+                           ApplicationBaseURL + currentMailbox + "/"
+                           + msguid + "/popupview");
 }
 
 function toggleMailSelect(sender) {
-  var row;
-  row = $(sender.name);
-  row.className = sender.checked ? "tableview_selected" : "tableview";
+   var row;
+   row = $(sender.name);
+   row.className = sender.checked ? "tableview_selected" : "tableview";
 }
 
 function clearSearch(sender) {
-  var searchField = window.$("search");
-  if (searchField) searchField.value="";
-  return true;
+   var searchField = window.$("search");
+   if (searchField) searchField.value="";
+   return true;
 }
 
 /* mail editor */
 
 function validateEditorInput(sender) {
-  var errortext = "";
-  var field;
-  
-  field = document.pageform.subject;
-  if (field.value == "")
-    errortext = errortext + labels.error_missingsubject + "\n";
-
-  if (!UIxRecipientSelectorHasRecipients())
-    errortext = errortext + labels.error_missingrecipients + "\n";
-  
-  if (errortext.length > 0) {
-    alert(labels.error_validationfailed.decodeEntities() + ":\n"
-          + errortext.decodeEntities());
-    return false;
-  }
-  return true;
+   var errortext = "";
+   var field;
+   
+   field = document.pageform.subject;
+   if (field.value == "")
+      errortext = errortext + labels.error_missingsubject + "\n";
+
+   if (!UIxRecipientSelectorHasRecipients())
+      errortext = errortext + labels.error_missingrecipients + "\n";
+   
+   if (errortext.length > 0) {
+      alert(labels.error_validationfailed.decodeEntities() + ":\n"
+           + errortext.decodeEntities());
+      return false;
+   }
+   return true;
 }
 
 function clickedEditorSend(sender) {
-  if (!validateEditorInput(sender))
-    return false;
+   if (!validateEditorInput(sender))
+      return false;
 
-  document.pageform.action="send";
-  document.pageform.submit();
-  // if everything is ok, close the window
-  return true;
+   document.pageform.action="send";
+   document.pageform.submit();
+   // if everything is ok, close the window
+                      return true;
 }
 
 function clickedEditorAttach(sender) {
-  var urlstr;
-  
-  urlstr = "viewAttachments";
-  window.open(urlstr, "SOGo_attach",
-             "width=320,height=320,resizable=1,scrollbars=1,toolbar=0," +
-             "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  return false; /* stop following the link */
-}
+   var urlstr;
+   
+   urlstr = "viewAttachments";
+   window.open(urlstr, "SOGo_attach",
+              "width=320,height=320,resizable=1,scrollbars=1,toolbar=0," +
+              "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+   return false; /* stop following the link */
+                    }
 
 function clickedEditorSave(sender) {
-  document.pageform.action="save";
-  document.pageform.submit();
-  refreshOpener();
-  return true;
+   document.pageform.action="save";
+   document.pageform.submit();
+   refreshOpener();
+   return true;
 }
 
 function clickedEditorDelete(sender) {
-  document.pageform.action="delete";
-  document.pageform.submit();
-  refreshOpener();
-  window.close();
-  return true;
+   document.pageform.action="delete";
+   document.pageform.submit();
+   refreshOpener();
+   window.close();
+   return true;
 }
 
 function openAddressbook(sender) {
-  var urlstr;
-  
-  urlstr = ApplicationBaseURL + "/../Contacts/?popup=YES";
-  var w = window.open(urlstr, "Addressbook",
-                      "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
-                      + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  w.focus();
+   var urlstr;
+   
+   urlstr = ApplicationBaseURL + "/../Contacts/?popup=YES";
+   var w = window.open(urlstr, "Addressbook",
+                      "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
+                      + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+   w.focus();
+
+   return false;
+}
+
+function onMenuSharing(event) {
+   var folderID = document.menuTarget.getAttribute("dataname");
+   var urlstr = URLForFolderID(folderID) + "/acls";
+   event.preventDefault();
 
-  return false;
+   openAclWindow(urlstr);
 }
 
 /* mail list DOM changes */
 
 function markMailInWindow(win, msguid, markread) {
-  var msgDiv;
-
-  msgDiv = win.$("div_" + msguid);
-  if (msgDiv) {
-    if (markread) {
-      msgDiv.removeClassName("mailer_unreadmailsubject");
-      msgDiv.addClassName("mailer_readmailsubject");
-      msgDiv = win.$("unreaddiv_" + msguid);
-      if (msgDiv)
-        {
-          msgDiv.setAttribute("class", "mailerUnreadIcon");
-          msgDiv.setAttribute("id", "readdiv_" + msguid);
-          msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
-          msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
-                              + " 'markMessageUnread', " + msguid
-                              + ", false);"
-                              +" return false;");
-          var title = msgDiv.getAttribute("title-markunread");
-          if (title)
-            msgDiv.setAttribute("title", title);
-        }
-    }
-    else {
-      msgDiv.removeClassName('mailer_readmailsubject');
-      msgDiv.addClassName('mailer_unreadmailsubject');
-      msgDiv = win.$("readdiv_" + msguid);
-      if (msgDiv)
-        {
-          msgDiv.setAttribute("class", "mailerReadIcon");
-          msgDiv.setAttribute("id", "unreaddiv_" + msguid);
-          msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
-          msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
-                              + " 'markMessageRead', " + msguid
-                              + ", true);"
-                              +" return false;");
-          var title = msgDiv.getAttribute("title-markread");
-          if (title)
-            msgDiv.setAttribute("title", title);
-        }
-    }
-    return true;
-  }
-  else
-    return false;
+   var msgDiv;
+
+   msgDiv = win.$("div_" + msguid);
+   if (msgDiv) {
+      if (markread) {
+        msgDiv.removeClassName("mailer_unreadmailsubject");
+        msgDiv.addClassName("mailer_readmailsubject");
+        msgDiv = win.$("unreaddiv_" + msguid);
+        if (msgDiv)
+        {
+           msgDiv.setAttribute("class", "mailerUnreadIcon");
+           msgDiv.setAttribute("id", "readdiv_" + msguid);
+           msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
+           msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
+                               + " 'markMessageUnread', " + msguid
+                               + ", false);"
+                               +" return false;");
+           var title = msgDiv.getAttribute("title-markunread");
+           if (title)
+              msgDiv.setAttribute("title", title);
+        }
+      }
+      else {
+        msgDiv.removeClassName('mailer_readmailsubject');
+        msgDiv.addClassName('mailer_unreadmailsubject');
+        msgDiv = win.$("readdiv_" + msguid);
+        if (msgDiv)
+        {
+           msgDiv.setAttribute("class", "mailerReadIcon");
+           msgDiv.setAttribute("id", "unreaddiv_" + msguid);
+           msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
+           msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
+                               + " 'markMessageRead', " + msguid
+                               + ", true);"
+                               +" return false;");
+           var title = msgDiv.getAttribute("title-markread");
+           if (title)
+              msgDiv.setAttribute("title", title);
+        }
+      }
+      return true;
+   }
+   else
+      return false;
 }
 
 function markMailReadInWindow(win, msguid) {
-  /* this is called by UIxMailView with window.opener */
-  return markMailInWindow(win, msguid, true);
+   /* this is called by UIxMailView with window.opener */
+       return markMailInWindow(win, msguid, true);
 }
 
 /* main window */
 
 function reopenToRemoveLocationBar() {
-  // we cannot really use this, see below at the close comment
-  if (window.locationbar && window.locationbar.visible) {
-    newwin = window.open(window.location.href, "SOGo",
-                        "width=800,height=600,resizable=1,scrollbars=1," +
-                        "toolbar=0,location=0,directories=0,status=0," + 
-                        "menubar=0,copyhistory=0");
-    if (newwin) {
-      window.close(); // this does only work for windows opened by scripts!
-      newwin.focus();
-      return true;
-    }
-    return false;
-  }
-  return true;
+   // we cannot really use this, see below at the close comment
+        if (window.locationbar && window.locationbar.visible) {
+           newwin = window.open(window.location.href, "SOGo",
+                                "width=800,height=600,resizable=1,scrollbars=1," +
+                                "toolbar=0,location=0,directories=0,status=0," + 
+                                "menubar=0,copyhistory=0");
+           if (newwin) {
+              window.close(); // this does only work for windows opened by scripts!
+                                                                    newwin.focus();
+              return true;
+           }
+           return false;
+        }
+   return true;
 }
 
 /* mail list reply */
 
 function openMessageWindowsForSelection(action) {
-  if (document.body.hasClassName("popup"))
-    win = openMessageWindow(window.messageId,
-                            window.messageURL + "/" + action /* url */);
-  else {
-     var messageList = $("messageList");
-     var rows  = messageList.getSelectedRowsId();
-     var idset = "";
-     for (var i = 0; i < rows.length; i++)
-       win = openMessageWindow(rows[i].substr(4)        /* msguid */,
-                               ApplicationBaseURL + currentMailbox
-                               + "/" + rows[i].substr(4)
-                               + "/" + action /* url */);
-  }
-
-  return false;
+   if (document.body.hasClassName("popup"))
+      win = openMessageWindow(window.messageId,
+                             window.messageURL + "/" + action /* url */);
+   else {
+      var messageList = $("messageList");
+      var rows  = messageList.getSelectedRowsId();
+      var idset = "";
+      for (var i = 0; i < rows.length; i++)
+        win = openMessageWindow(rows[i].substr(4)        /* msguid */,
+                                ApplicationBaseURL + currentMailbox
+                                + "/" + rows[i].substr(4)
+                                + "/" + action /* url */);
+   }
+
+   return false;
 }
 
 function mailListMarkMessage(event) {
-  var http = createHTTPClient();
-  var url = ApplicationBaseURL + currentMailbox + "/" + action + "?uid=" + msguid;
-
-  if (http) {
-    // TODO: add parameter to signal that we are only interested in OK
-    http.open("POST", url + "&jsonly=1", false /* not async */);
-    http.send("");
-    if (http.status != 200) {
-      // TODO: refresh page?
-      alert("Message Mark Failed: " + http.statusText);
-      window.location.reload();
-    }
-    else {
-      markMailInWindow(window, msguid, markread);
-    }
-  }
-  else {
-    window.location.href = url;
-  }
+   var http = createHTTPClient();
+   var url = ApplicationBaseURL + currentMailbox + "/" + action + "?uid=" + msguid;
+
+   if (http) {
+      // TODO: add parameter to signal that we are only interested in OK
+                 http.open("POST", url + "&jsonly=1", false /* not async */);
+      http.send("");
+      if (http.status != 200) {
+        // TODO: refresh page?
+                    alert("Message Mark Failed: " + http.statusText);
+        window.location.reload();
+      }
+      else {
+        markMailInWindow(window, msguid, markread);
+      }
+   }
+   else {
+      window.location.href = url;
+   }
 }
 
 /* maillist row highlight */
@@ -233,148 +245,148 @@ function mailListMarkMessage(event) {
 var oldMaillistHighlight = null; // to remember deleted/selected style
 
 function ml_highlight(sender) {
-  oldMaillistHighlight = sender.className;
-  if (oldMaillistHighlight == "tableview_highlight")
-    oldMaillistHighlight = null;
-  sender.className = "tableview_highlight";
+   oldMaillistHighlight = sender.className;
+   if (oldMaillistHighlight == "tableview_highlight")
+      oldMaillistHighlight = null;
+   sender.className = "tableview_highlight";
 }
 
 function ml_lowlight(sender) {
-  if (oldMaillistHighlight) {
-    sender.className = oldMaillistHighlight;
-    oldMaillistHighlight = null;
-  }
-  else
-    sender.className = "tableview";
+   if (oldMaillistHighlight) {
+      sender.className = oldMaillistHighlight;
+      oldMaillistHighlight = null;
+   }
+   else
+      sender.className = "tableview";
 }
 
 
 /* folder operations */
 
 function ctxFolderAdd(sender) {
-  var folderName;
-  
-  folderName = prompt("Foldername: ");
-  if (folderName == undefined)
-    return false;
-  if (folderName == "")
-    return false;
-  
-  // TODO: should use a form-POST or AJAX
-  window.location.href = "createFolder?name=" + escape(folderName);
-  return false;
+   var folderName;
+   
+   folderName = prompt("Foldername: ");
+   if (folderName == undefined)
+      return false;
+   if (folderName == "")
+      return false;
+   
+   // TODO: should use a form-POST or AJAX
+              window.location.href = "createFolder?name=" + escape(folderName);
+   return false;
 }
 
 function ctxFolderDelete(sender) {
-  if (!confirm("Delete current folder?").decodeEntities())
-    return false;
-  
-  // TODO: should use a form-POST or AJAX
-  window.location.href = "deleteFolder";
-  return false;
+   if (!confirm("Delete current folder?").decodeEntities())
+      return false;
+   
+   // TODO: should use a form-POST or AJAX
+              window.location.href = "deleteFolder";
+   return false;
 }
 
 /* bulk delete of messages */
 
 function uixDeleteSelectedMessages(sender) {
-  var failCount = 0;
-  
-  var messageList = $("messageList");
-  var rowIds = messageList.getSelectedRowsId();
-
-  for (var i = 0; i < rowIds.length; i++) {
-    var url, http;
-    var rowId = rowIds[i].substr(4);
-    /* send AJAX request (synchronously) */
-
-    var messageId = currentMailbox + "/" + rowId;
-    url = ApplicationBaseURL + messageId + "/trash?jsonly=1";
-    http = createHTTPClient();
-    http.open("GET", url, false /* not async */);
-    http.send("");
-    if (http.status != 200) { /* request failed */
-      failCount++;
+   var failCount = 0;
+   
+   var messageList = $("messageList");
+   var rowIds = messageList.getSelectedRowsId();
+
+   for (var i = 0; i < rowIds.length; i++) {
+      var url, http;
+      var rowId = rowIds[i].substr(4);
+      /* send AJAX request (synchronously) */
+
+         var messageId = currentMailbox + "/" + rowId;
+      url = ApplicationBaseURL + messageId + "/trash?jsonly=1";
+      http = createHTTPClient();
+      http.open("GET", url, false /* not async */);
+      http.send("");
+      if (http.status != 200) { /* request failed */
+                                   failCount++;
       http = null;
       continue;
-    } else {
-      deleteCachedMessage(messageId);
-      if (currentMessages[currentMailbox] == rowId) {
-        var div = $('messageContent');
-        div.innerHTML = "";
-        currentMessages[currentMailbox] = null;
+      } else {
+        deleteCachedMessage(messageId);
+        if (currentMessages[currentMailbox] == rowId) {
+           var div = $('messageContent');
+           div.innerHTML = "";
+           currentMessages[currentMailbox] = null;
+        }
       }
-    }
-    http = null;
+      http = null;
 
-    /* remove from page */
+      /* remove from page */
 
-    /* line-through would be nicer, but hiding is OK too */
-    var row = $(rowIds[i]);
-    row.parentNode.removeChild(row);
-  }
+         /* line-through would be nicer, but hiding is OK too */
+         var row = $(rowIds[i]);
+      row.parentNode.removeChild(row);
+   }
 
-  if (failCount > 0)
-    alert("Could not delete " + failCount + " messages!");
-  
-  return false;
+   if (failCount > 0)
+      alert("Could not delete " + failCount + " messages!");
+   
+   return false;
 }
 
 function moveMessages(rowIds, folder) {
-  var failCount = 0;
-
-  for (var i = 0; i < rowIds.length; i++) {
-    var url, http;
-
-    /* send AJAX request (synchronously) */
-    
-    var messageId = currentMailbox + "/" + rowIds[i];
-    url = ApplicationBaseURL + messageId + "/move?jsonly=1&tofolder=" + folder;
-    http = createHTTPClient();
-    http.open("GET", url, false /* not async */);
-    http.send("");
-    if (http.status == 200) {
-      var row = $("row_" + rowIds[i]);
-      row.parentNode.removeChild(row);
-      deleteCachedMessage(messageId);
-      if (currentMessages[currentMailbox] == rowIds[i]) {
-        var div = $('messageContent');
-        div.innerHTML = "";
-        currentMessages[currentMailbox] = null;
+   var failCount = 0;
+
+   for (var i = 0; i < rowIds.length; i++) {
+      var url, http;
+
+      /* send AJAX request (synchronously) */
+         
+         var messageId = currentMailbox + "/" + rowIds[i];
+      url = ApplicationBaseURL + messageId + "/move?jsonly=1&tofolder=" + folder;
+      http = createHTTPClient();
+      http.open("GET", url, false /* not async */);
+      http.send("");
+      if (http.status == 200) {
+        var row = $("row_" + rowIds[i]);
+        row.parentNode.removeChild(row);
+        deleteCachedMessage(messageId);
+        if (currentMessages[currentMailbox] == rowIds[i]) {
+           var div = $('messageContent');
+           div.innerHTML = "";
+           currentMessages[currentMailbox] = null;
+        }
       }
-    }
-    else /* request failed */
-      failCount++;
+      else /* request failed */
+             failCount++;
 
-    /* remove from page */
+      /* remove from page */
 
-    /* line-through would be nicer, but hiding is OK too */
-  }
+         /* line-through would be nicer, but hiding is OK too */
+         }
 
-  if (failCount > 0)
-    alert("Could not move " + failCount + " messages!");
-  
-  return failCount;
+   if (failCount > 0)
+      alert("Could not move " + failCount + " messages!");
+   
+   return failCount;
 }
 
 function onMenuDeleteMessage(event) {
-  uixDeleteSelectedMessages();
-  event.preventDefault();
+   uixDeleteSelectedMessages();
+   event.preventDefault();
 }
 
 function onMailboxTreeItemClick(event) {
-  var topNode = $("d");
-  var mailbox = this.parentNode.getAttribute("dataname");
+   var topNode = $("d");
+   var mailbox = this.parentNode.getAttribute("dataname");
 
-  if (topNode.selectedEntry) {
-    log ("deselecting");
-    topNode.selectedEntry.deselect();
-  }
-  this.select();
-  topNode.selectedEntry = this;
+   if (topNode.selectedEntry) {
+      log ("deselecting");
+      topNode.selectedEntry.deselect();
+   }
+   this.select();
+   topNode.selectedEntry = this;
 
-  if (this.parentNode.getAttribute("datatype") != "account")
-     openMailbox(mailbox);
-  event.preventDefault();
+   if (this.parentNode.getAttribute("datatype") != "account")
+      openMailbox(mailbox);
+   event.preventDefault();
 }
 
 function _refreshWindowMailbox() {
@@ -390,269 +402,267 @@ function refreshMailbox() {
 }
 
 function openMailbox(mailbox, reload) {
-  if (mailbox != currentMailbox || reload) {
-    currentMailbox = mailbox;
-    var url = ApplicationBaseURL + mailbox + "/view?noframe=1&desc=1";
-    var mailboxContent = $("mailboxContent");
-    var rightDragHandle = $("rightDragHandle");
-    var messageContent = $("messageContent");
-    messageContent.innerHTML = '';
-    if (mailbox.lastIndexOf("/") == 0) {
-      var url = (ApplicationBaseURL + currentMailbox + "/"
-                 + "/view?noframe=1");
-      if (document.messageAjaxRequest) {
-        document.messageAjaxRequest.aborted = true;
-        document.messageAjaxRequest.abort();
-      }
-      document.messageAjaxRequest
-        = triggerAjaxRequest(url, messageCallback);
-      mailboxContent.innerHTML = '';
-      mailboxContent.style.visibility = "hidden;";
-      rightDragHandle.style.visibility = "hidden;";
-      messageContent.style.top = "0px;";
-    } else {
-      if (document.messageListAjaxRequest) {
-        document.messageListAjaxRequest.aborted = true;
-        document.messageListAjaxRequest.abort();
-      }
-      if (currentMessages[mailbox]) {
-        loadMessage(currentMessages[mailbox]);
-        url += '&pageforuid=' + currentMessages[mailbox];
-      }
-      document.messageListAjaxRequest
-        = triggerAjaxRequest(url, messageListCallback,
-                             currentMessages[mailbox]);
-      if (mailboxContent.style.visibility == "hidden") {
-        mailboxContent.style.visibility = "visible;";
-        rightDragHandle.style.visibility = "visible;";
-        messageContent.style.top = (rightDragHandle.offsetTop
-                                    + rightDragHandle.offsetHeight
-                                    + 'px;');
+   if (mailbox != currentMailbox || reload) {
+      currentMailbox = mailbox;
+      var url = ApplicationBaseURL + mailbox + "/view?noframe=1&desc=1";
+      var mailboxContent = $("mailboxContent");
+      var rightDragHandle = $("rightDragHandle");
+      var messageContent = $("messageContent");
+      messageContent.innerHTML = '';
+      if (mailbox.lastIndexOf("/") == 0) {
+        var url = (ApplicationBaseURL + currentMailbox + "/"
+                   + "/view?noframe=1");
+        if (document.messageAjaxRequest) {
+           document.messageAjaxRequest.aborted = true;
+           document.messageAjaxRequest.abort();
+        }
+        document.messageAjaxRequest
+           = triggerAjaxRequest(url, messageCallback);
+        mailboxContent.innerHTML = '';
+        mailboxContent.style.visibility = "hidden;";
+        rightDragHandle.style.visibility = "hidden;";
+        messageContent.style.top = "0px;";
+      } else {
+        if (document.messageListAjaxRequest) {
+           document.messageListAjaxRequest.aborted = true;
+           document.messageListAjaxRequest.abort();
+        }
+        if (currentMessages[mailbox]) {
+           loadMessage(currentMessages[mailbox]);
+           url += '&pageforuid=' + currentMessages[mailbox];
+        }
+        document.messageListAjaxRequest
+           = triggerAjaxRequest(url, messageListCallback,
+                                currentMessages[mailbox]);
+        if (mailboxContent.style.visibility == "hidden") {
+           mailboxContent.style.visibility = "visible;";
+           rightDragHandle.style.visibility = "visible;";
+           messageContent.style.top = (rightDragHandle.offsetTop
+                                       + rightDragHandle.offsetHeight
+                                       + 'px;');
+        }
       }
-    }
-  }
-//   triggerAjaxRequest(mailbox, 'toolbar', toolbarCallback);
+   }
+   //   triggerAjaxRequest(mailbox, 'toolbar', toolbarCallback);
 }
 
 function openMailboxAtIndex(element) {
-  var idx = element.getAttribute("idx");
-  var url = ApplicationBaseURL + currentMailbox + "/view?noframe=1&idx=" + idx;
+   var idx = element.getAttribute("idx");
+   var url = ApplicationBaseURL + currentMailbox + "/view?noframe=1&idx=" + idx;
 
-  if (document.messageListAjaxRequest) {
-    document.messageListAjaxRequest.aborted = true;
-    document.messageListAjaxRequest.abort();
-  }
-  document.messageListAjaxRequest
-    = triggerAjaxRequest(url, messageListCallback);
+   if (document.messageListAjaxRequest) {
+      document.messageListAjaxRequest.aborted = true;
+      document.messageListAjaxRequest.abort();
+   }
+   document.messageListAjaxRequest
+      = triggerAjaxRequest(url, messageListCallback);
 
-  return false;
+   return false;
 }
 
 function messageListCallback(http) {
-  var div = $('mailboxContent');
-
-  if (http.readyState == 4
-      && http.status == 200) {
-    document.messageListAjaxRequest = null;
-    div.innerHTML = http.responseText;
-    var selected = http.callbackData;
-    if (selected) {
-      var row = $('row_' + selected);
-      row.select();
-    }
-    configureMessageListEvents();
-    configureSortableTableHeaders();
-  }
-  else
-    log ("ajax fuckage");
+   var div = $('mailboxContent');
+
+   if (http.readyState == 4
+       && http.status == 200) {
+      document.messageListAjaxRequest = null;
+      div.innerHTML = http.responseText;
+      var selected = http.callbackData;
+      if (selected) {
+        var row = $('row_' + selected);
+        row.select();
+      }
+      configureMessageListEvents();
+      configureSortableTableHeaders();
+   }
+   else
+      log("ajax fuckage");
 }
 
 function onMessageContextMenu(event) {
-  var menu = $('messageListMenu');
-  menu.addEventListener("hideMenu", onMessageContextMenuHide, false);
-  onMenuClick(event, 'messageListMenu');
+   log("messagelistmenu");
+   var menu = $('messageListMenu');
+   Event.observe(menu, "hideMenu", onMessageContextMenuHide);
+   popupMenu(event, "messageListMenu", this);
 
-  var topNode = $('messageList');
-  var selectedNodes = topNode.getSelectedRows();
-  for (var i = 0; i < selectedNodes.length; i++)
-    selectedNodes[i].deselect();
-  topNode.menuSelectedRows = selectedNodes;
-  topNode.menuSelectedEntry = this;
-  this.select();
+   var topNode = $('messageList');
+   var selectedNodes = topNode.getSelectedRows();
+   for (var i = 0; i < selectedNodes.length; i++)
+      selectedNodes[i].deselect();
+   topNode.menuSelectedRows = selectedNodes;
+   topNode.menuSelectedEntry = this;
+   this.select();
 }
 
 function onMessageContextMenuHide(event) {
-  var topNode = $('messageList');
+   var topNode = $('messageList');
 
-  if (topNode.menuSelectedEntry) {
-    topNode.menuSelectedEntry.deselect();
-    topNode.menuSelectedEntry = null;
-  }
-  if (topNode.menuSelectedRows) {
-    var nodes = topNode.menuSelectedRows;
-    for (var i = 0; i < nodes.length; i++)
-      nodes[i].select();
-    topNode.menuSelectedRows = null;
-  }
+   if (topNode.menuSelectedEntry) {
+      topNode.menuSelectedEntry.deselect();
+      topNode.menuSelectedEntry = null;
+   }
+   if (topNode.menuSelectedRows) {
+      var nodes = topNode.menuSelectedRows;
+      for (var i = 0; i < nodes.length; i++)
+        nodes[i].select();
+      topNode.menuSelectedRows = null;
+   }
 }
 
 function onFolderMenuClick(event) {
-  var onhide, menuName;
-  
-  var menutype = this.parentNode.getAttribute("datatype");
-//   log("parentNode: " + this.parentNode.tagName);
-//   log("menutype: " + menutype);
-  if (menutype) {
-    if (menutype == "inbox") {
-      menuName = "inboxIconMenu";
-    } else if (menutype == "account") {
-      menuName = "accountIconMenu";
-    } else if (menutype == "trash") {
-      menuName = "trashIconMenu";
-    } else {
+   var onhide, menuName;
+   
+   var menutype = this.parentNode.getAttribute("datatype");
+   //   log("parentNode: " + this.parentNode.tagName);
+   //   log("menutype: " + menutype);
+   if (menutype) {
+      if (menutype == "inbox") {
+        menuName = "inboxIconMenu";
+      } else if (menutype == "account") {
+        menuName = "accountIconMenu";
+      } else if (menutype == "trash") {
+        menuName = "trashIconMenu";
+      } else {
+        menuName = "mailboxIconMenu";
+      }
+   } else {
       menuName = "mailboxIconMenu";
-    }
-  } else {
-    menuName = "mailboxIconMenu";
-  }
+   }
 
-  var menu = $(menuName);
-  menu.addEventListener("hideMenu", onFolderMenuHide, false);
-  onMenuClick(event, menuName);
+   var menu = $(menuName);
+   Event.observe(menu, "hideMenu", onFolderMenuHide);
+   popupMenu(event, menuName, this.parentNode);
 
-  var topNode = $('d');
-  if (topNode.selectedEntry)
-    topNode.selectedEntry.deselect();
-  if (topNode.menuSelectedEntry)
-    topNode.menuSelectedEntry.deselect();
-  topNode.menuSelectedEntry = this;
-  this.select();
+   var topNode = $('d');
+   if (topNode.selectedEntry)
+      topNode.selectedEntry.deselect();
+   if (topNode.menuSelectedEntry)
+      topNode.menuSelectedEntry.deselect();
+   topNode.menuSelectedEntry = this;
+   this.select();
 }
 
 function onFolderMenuHide(event) {
-  var topNode = $('d');
+   var topNode = $('d');
 
-  if (topNode.menuSelectedEntry) {
-    topNode.menuSelectedEntry.deselect();
-    topNode.menuSelectedEntry = null;
-  }
-  if (topNode.selectedEntry)
-    topNode.selectedEntry.select();
+   if (topNode.menuSelectedEntry) {
+      topNode.menuSelectedEntry.deselect();
+      topNode.menuSelectedEntry = null;
+   }
+   if (topNode.selectedEntry)
+      topNode.selectedEntry.select();
 }
 
 function deleteCachedMessage(messageId) {
-  var done = false;
-  var counter = 0;
-
-  while (counter < cachedMessages.length
-         && !done)
-    if (cachedMessages[counter]
-        && cachedMessages[counter]['idx'] == messageId) {
-      cachedMessages.splice(counter, 1);
-      done = true;
-    }
-    else
-      counter++;
+   var done = false;
+   var counter = 0;
+
+   while (counter < cachedMessages.length
+         && !done)
+      if (cachedMessages[counter]
+         && cachedMessages[counter]['idx'] == messageId) {
+        cachedMessages.splice(counter, 1);
+        done = true;
+      }
+      else
+        counter++;
 }
 
 function getCachedMessage(idx) {
-  var message = null;
-  var counter = 0;
-
-  while (counter < cachedMessages.length
-         && message == null)
-    if (cachedMessages[counter]
-        && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
-      message = cachedMessages[counter];
-    else
-      counter++;
+   var message = null;
+   var counter = 0;
+
+   while (counter < cachedMessages.length
+         && message == null)
+      if (cachedMessages[counter]
+         && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
+        message = cachedMessages[counter];
+      else
+        counter++;
 
-  return message;
+   return message;
 }
 
 function storeCachedMessage(cachedMessage) {
-  var oldest = -1;
-  var timeOldest = -1;
-  var counter = 0;
-
-  if (cachedMessages.length < maxCachedMessages)
-    oldest = cachedMessages.length;
-  else {
-    while (cachedMessages[counter]) {
-      if (oldest == -1
-          || cachedMessages[counter]['time'] < timeOldest) {
-        oldest = counter;
-        timeOldest = cachedMessages[counter]['time'];
+   var oldest = -1;
+   var timeOldest = -1;
+   var counter = 0;
+
+   if (cachedMessages.length < maxCachedMessages)
+      oldest = cachedMessages.length;
+   else {
+      while (cachedMessages[counter]) {
+        if (oldest == -1
+            || cachedMessages[counter]['time'] < timeOldest) {
+           oldest = counter;
+           timeOldest = cachedMessages[counter]['time'];
+        }
+        counter++;
       }
-      counter++;
-    }
 
-    if (oldest == -1)
-      oldest = 0;
-  }
+      if (oldest == -1)
+        oldest = 0;
+   }
 
-  cachedMessages[oldest] = cachedMessage;
+   cachedMessages[oldest] = cachedMessage;
 }
 
 function onMessageSelectionChange() {
-  var rows = this.getSelectedRowsId();
-  if (rows.length == 1) {
-    var idx = rows[0].substr(4);
+   var rows = this.getSelectedRowsId();
+   if (rows.length == 1) {
+      var idx = rows[0].substr(4);
 
-    if (currentMessages[currentMailbox] != idx) {
-      currentMessages[currentMailbox] = idx;
-      loadMessage(idx);
-    }
-  }
+      if (currentMessages[currentMailbox] != idx) {
+        currentMessages[currentMailbox] = idx;
+        loadMessage(idx);
+      }
+   }
 }
 
 function loadMessage(idx) {
-  if (document.messageAjaxRequest) {
-    document.messageAjaxRequest.aborted = true;
-    document.messageAjaxRequest.abort();
-  }
-
-  var cachedMessage = getCachedMessage(idx);
-
-  if (cachedMessage == null) {
-    var url = (ApplicationBaseURL + currentMailbox + "/"
-               + idx + "/view?noframe=1");
-    document.messageAjaxRequest
-      = triggerAjaxRequest(url, messageCallback, idx);
-    markMailInWindow(window, idx, true);
-  } else {
-    var div = $('messageContent');
-    div.innerHTML = cachedMessage['text'];
-    cachedMessage['time'] = (new Date()).getTime();
-    document.messageAjaxRequest = null;
-    configureLinksInMessage();
-  }
+   if (document.messageAjaxRequest) {
+      document.messageAjaxRequest.aborted = true;
+      document.messageAjaxRequest.abort();
+   }
+
+   var cachedMessage = getCachedMessage(idx);
+
+   if (cachedMessage == null) {
+      var url = (ApplicationBaseURL + currentMailbox + "/"
+                + idx + "/view?noframe=1");
+      document.messageAjaxRequest
+        = triggerAjaxRequest(url, messageCallback, idx);
+      markMailInWindow(window, idx, true);
+   } else {
+      var div = $('messageContent');
+      div.innerHTML = cachedMessage['text'];
+      cachedMessage['time'] = (new Date()).getTime();
+      document.messageAjaxRequest = null;
+      configureLinksInMessage();
+   }
 }
 
 function configureLinksInMessage() {
    var messageDiv = $('messageContent');
    var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
                                                        messageDiv)[0];
-   mailContentDiv.addEventListener("contextmenu", onMessageContentMenu, false);
+   Event.observe(mailContentDiv, "contextmenu", onMessageContentMenu);
    var anchors = messageDiv.getElementsByTagName('a');
    for (var i = 0; i < anchors.length; i++)
       if (anchors[i].href.substring(0,7) == "mailto:") {
-        anchors[i].addEventListener("click", onEmailAddressClick, false);
-        anchors[i].addEventListener("contextmenu", onEmailAddressClick,
-                                    false);
+        Event.observe(anchors[i], "click", onEmailAddressClick);
+        Event.observe(anchors[i], "contextmenu", onEmailAddressClick);
       }
       else
-        anchors[i].addEventListener("click", onMessageAnchorClick, false);
+        Event.observe(anchors[i], "click", onMessageAnchorClick);
 }
 
 function onMessageContentMenu(event) {
-   onMenuClick(event, 'messageContentMenu');
-   event.preventDefault();
-};
+   popupMenu(event, 'messageContentMenu', this);
+}
 
 function onEmailAddressClick(event) {
-   onMenuClick(event, 'addressMenu');
-   event.preventDefault();
+   popupMenu(event, 'addressMenu', this);
 }
 
 function onMessageAnchorClick (event) {
@@ -661,48 +671,48 @@ function onMessageAnchorClick (event) {
 }
 
 function messageCallback(http) {
-  var div = $('messageContent');
-
-  if (http.readyState == 4
-      && http.status == 200) {
-    document.messageAjaxRequest = null;
-    div.innerHTML = http.responseText;
-    configureLinksInMessage();
-
-    if (http.callbackData) {
-      var cachedMessage = new Array();
-      cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
-      cachedMessage['time'] = (new Date()).getTime();
-      cachedMessage['text'] = http.responseText;
-      if (cachedMessage['text'].length < 30000)
-        storeCachedMessage(cachedMessage);
-    }
-  }
-  else
-    log ("ajax fuckage");
+   var div = $('messageContent');
+
+   if (http.readyState == 4
+       && http.status == 200) {
+      document.messageAjaxRequest = null;
+      div.innerHTML = http.responseText;
+      configureLinksInMessage();
+
+      if (http.callbackData) {
+        var cachedMessage = new Array();
+        cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
+        cachedMessage['time'] = (new Date()).getTime();
+        cachedMessage['text'] = http.responseText;
+        if (cachedMessage['text'].length < 30000)
+           storeCachedMessage(cachedMessage);
+      }
+   }
+   else
+      log ("ajax fuckage");
 }
 
 function processMailboxMenuAction(mailbox) {
-  var currentNode, upperNode;
-  var mailboxName;
-  var action;
+   var currentNode, upperNode;
+   var mailboxName;
+   var action;
 
-  mailboxName = mailbox.getAttribute('mailboxname');
-  currentNode = mailbox;
-  upperNode = null;
+   mailboxName = mailbox.getAttribute('mailboxname');
+   currentNode = mailbox;
+   upperNode = null;
 
-  while (currentNode
-         && !currentNode.hasAttribute('mailboxaction'))
-    currentNode = currentNode.parentNode.parentNode.parentMenuItem;
+   while (currentNode
+         && !currentNode.hasAttribute('mailboxaction'))
+      currentNode = currentNode.parentNode.parentNode.parentMenuItem;
 
-  if (currentNode)
-    {
+   if (currentNode)
+   {
       action = currentNode.getAttribute('mailboxaction');
-//       var rows  = collectSelectedRows();
-//       var rString = rows.join(', ');
-//       alert("performing '" + action + "' on " + rString
-//             + " to " + mailboxName);
-    }
+      //       var rows  = collectSelectedRows();
+      //       var rString = rows.join(', ');
+      //       alert("performing '" + action + "' on " + rString
+                    //             + " to " + mailboxName);
+   }
 }
 
 var rowSelectionCount = 0;
@@ -710,28 +720,28 @@ var rowSelectionCount = 0;
 validateControls();
 
 function showElement(e, shouldShow) {
-  e.style.display = shouldShow ? "" : "none";
+   e.style.display = shouldShow ? "" : "none";
 }
 
 function enableElement(e, shouldEnable) {
-  if(!e)
-    return;
-  if(shouldEnable) {
-    if(e.hasAttribute("disabled"))
-      e.removeAttribute("disabled");
-  }
-  else {
-    e.setAttribute("disabled", "1");
-  }
+   if(!e)
+      return;
+   if(shouldEnable) {
+      if(e.hasAttribute("disabled"))
+        e.removeAttribute("disabled");
+   }
+   else {
+      e.setAttribute("disabled", "1");
+   }
 }
 
 function validateControls() {
-  var e = $("moveto");
-  this.enableElement(e, rowSelectionCount > 0);
+   var e = $("moveto");
+   this.enableElement(e, rowSelectionCount > 0);
 }
 
 function moveTo(uri) {
-  alert("MoveTo: " + uri);
+   alert("MoveTo: " + uri);
 }
 
 function deleteSelectedMails() {
@@ -755,45 +765,45 @@ function onMenuForwardMessage(event) {
 }
 
 /* contacts */
-function newContactFromEmail(sender) {
-  var mailto = sender.parentNode.parentNode.menuTarget.innerHTML;
-
-//   var emailre
-//     = /([a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z])/g;
-//   emailre.exec(mailto);
-//   email = RegExp.$1;
-
-//   var namere = /(\w[\w\ _-]+)\ (&lt;|<)/;
-//   var c_name = '';
-//   if (namere.test(mailto)) {
-//     namere.exec(mailto);
-//     c_name += RegExp.$1;
-//   }
-
-  var email = extractEmailAddress(mailto);
-  var c_name = extractEmailName(mailto);
-  if (email.length > 0)
-    {
+function newContactFromEmail(event) {
+   var mailto = document.menuTarget.innerHTML;
+
+   //   var emailre
+          //     = /([a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z])/g;
+   //   emailre.exec(mailto);
+   //   email = RegExp.$1;
+
+   //   var namere = /(\w[\w\ _-]+)\ (&lt;|<)/;
+   //   var c_name = '';
+   //   if (namere.test(mailto)) {
+      //     namere.exec(mailto);
+      //     c_name += RegExp.$1;
+      //   }
+
+   var email = extractEmailAddress(mailto);
+   var c_name = extractEmailName(mailto);
+   if (email.length > 0)
+   {
       var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
       if (c_name)
-        url += "&contactFN=" + c_name;
+        url += "&contactFN=" + c_name;
       w = window.open(url, null,
                       "width=546,height=490,resizable=1,scrollbars=1,toolbar=0,"
                       + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
       w.focus();
-    }
+   }
 
-  return false; /* stop following the link */
-}
+   return false; /* stop following the link */
+                    }
 
 function newEmailTo(sender) {
-  return openMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
+   return openMailTo(document.menuTarget.innerHTML);
 }
 
 function expandUpperTree(node) {
-  var currentNode = node.parentNode;
+   var currentNode = node.parentNode;
 
-  while (currentNode.className != "dtree") {
+   while (currentNode.className != "dtree") {
       if (currentNode.className == 'clip') {
         var id = currentNode.getAttribute("id");
         var number = parseInt(id.substr(2));
@@ -803,204 +813,203 @@ function expandUpperTree(node) {
         }
       }
       currentNode = currentNode.parentNode;
-  }
+   }
 }
 
 function initMailboxSelection(mailboxName) {
-  currentMailbox = mailboxName;
-//   log("initMailboxSelection: " + mailboxName);
-  var tree = $("d");
-  var treeNodes = document.getElementsByClassName("dTreeNode", tree);
-  var i = 0;
-  while (i < treeNodes.length
-         && treeNodes[i].getAttribute("dataname") != currentMailbox)
-    i++;
-  if (i < treeNodes.length) {
-//     log ("found mailbox");
-    var links = document.getElementsByClassName("node", treeNodes[i]);
-    if (tree.selectedEntry)
-      tree.selectedEntry.deselect();
-    links[0].select();
-    tree.selectedEntry = links[0];
-    expandUpperTree(links[0]);
-  }
+   currentMailbox = mailboxName;
+   //   log("initMailboxSelection: " + mailboxName);
+   var tree = $("d");
+   var treeNodes = document.getElementsByClassName("dTreeNode", tree);
+   var i = 0;
+   while (i < treeNodes.length
+         && treeNodes[i].getAttribute("dataname") != currentMailbox)
+      i++;
+   if (i < treeNodes.length) {
+      //     log ("found mailbox");
+      var links = document.getElementsByClassName("node", treeNodes[i]);
+      if (tree.selectedEntry)
+        tree.selectedEntry.deselect();
+      links[0].select();
+      tree.selectedEntry = links[0];
+      expandUpperTree(links[0]);
+   }
 }
 
 function onHeaderClick(event) {
-  if (document.messageListAjaxRequest) {
-    document.messageListAjaxRequest.aborted = true;
-    document.messageListAjaxRequest.abort();
-  }
-  url = ApplicationBaseURL + currentMailbox + "/" + this.link;
-  if (!this.link.match(/noframe=/))
-    url += "&noframe=1";
-  document.messageListAjaxRequest
-    = triggerAjaxRequest(url, messageListCallback);
+   if (document.messageListAjaxRequest) {
+      document.messageListAjaxRequest.aborted = true;
+      document.messageListAjaxRequest.abort();
+   }
+   url = ApplicationBaseURL + currentMailbox + "/" + this.link;
+   if (!this.link.match(/noframe=/))
+      url += "&noframe=1";
+   document.messageListAjaxRequest
+      = triggerAjaxRequest(url, messageListCallback);
 
-  event.preventDefault();
+   event.preventDefault();
 }
 
 function onSearchFormSubmit() {
-  log ("search not implemented");
+   log ("search not implemented");
 
-  return false;
+   return false;
 }
 
 function pouetpouet(event) {
-  window.alert("pouet pouet");
+   window.alert("pouet pouet");
 }
 
 var mailboxSpanAcceptType = function(type) {
-  return (type == "mailRow");
+   return (type == "mailRow");
 }
 
 var mailboxSpanEnter = function() {
-  this.addClassName("_dragOver");
+   this.addClassName("_dragOver");
 }
 
 var mailboxSpanExit = function() {
-  this.removeClassName("_dragOver");
+   this.removeClassName("_dragOver");
 }
 
 var mailboxSpanDrop = function(data) {
-  var success = false;
+   var success = false;
 
-  if (data) {
-    var folder = this.parentNode.parentNode.getAttribute("dataname");
-    if (folder != currentMailbox)
-      success = (moveMessages(data, folder) == 0);
-  }
-  else
-    success = false;
+   if (data) {
+      var folder = this.parentNode.parentNode.getAttribute("dataname");
+      if (folder != currentMailbox)
+        success = (moveMessages(data, folder) == 0);
+   }
+   else
+   success = false;
 
-  return success;
+   return success;
 }
 
 var plusSignEnter = function() {
-  var nodeNr = parseInt(this.id.substr(2));
-  if (!d.aNodes[nodeNr]._io)
-    this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
+   var nodeNr = parseInt(this.id.substr(2));
+   if (!d.aNodes[nodeNr]._io)
+   this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
 }
 
 var plusSignExit = function() {
-  if (this.plusSignTimer) {
-    clearTimeout(this.plusSignTimer);
-    this.plusSignTimer = null;
-  }
+   if (this.plusSignTimer) {
+      clearTimeout(this.plusSignTimer);
+      this.plusSignTimer = null;
+   }
 }
 
 function openPlusSign(nodeNr) {
-  d.nodeStatus(1, nodeNr, d.aNodes[nodeNr]._ls);
-  d.aNodes[nodeNr]._io = 1;
-  this.plusSignTimer = null;
+   d.nodeStatus(1, nodeNr, d.aNodes[nodeNr]._ls);
+   d.aNodes[nodeNr]._io = 1;
+   this.plusSignTimer = null;
 }
 
 var messageListGhost = function () {
-  var newDiv = document.createElement("div");
-//   newDiv.style.width = "25px;";
-//   newDiv.style.height = "25px;";
-  newDiv.style.backgroundColor = "#aae;";
-  newDiv.style.border = "2px solid #a3a;";
-  newDiv.style.padding = "5px;";
-  newDiv.ghostOffsetX = 10;
-  newDiv.ghostOffsetY = 5;
+   var newDiv = document.createElement("div");
+   //   newDiv.style.width = "25px;";
+   //   newDiv.style.height = "25px;";
+   newDiv.style.backgroundColor = "#aae;";
+   newDiv.style.border = "2px solid #a3a;";
+   newDiv.style.padding = "5px;";
+   newDiv.ghostOffsetX = 10;
+   newDiv.ghostOffsetY = 5;
 
-  var imgCode = '<img src="' + ResourcesURL + '/message-mail.png" />';
+   var imgCode = '<img src="' + ResourcesURL + '/message-mail.png" />';
 
-  var current = this;
-  while (!current.getSelectedRows)
-    current = current.parentNode;
-  var count = current.getSelectedRows().length;
-  var text = imgCode + '<br />' + count + ' messages...';
-  newDiv.innerHTML = text;
+   var current = this;
+   while (!current.getSelectedRows)
+   current = current.parentNode;
+   var count = current.getSelectedRows().length;
+   var text = imgCode + '<br />' + count + ' messages...';
+   newDiv.innerHTML = text;
 
-  return newDiv;
+   return newDiv;
 }
 
 var messageListData = function(type) {
-  var rows = this.parentNode.parentNode.getSelectedRowsId();
-  var msgIds = new Array();
-  for (var i = 0; i < rows.length; i++)
-    msgIds.push(rows[i].substr(4));
+   var rows = this.parentNode.parentNode.getSelectedRowsId();
+   var msgIds = new Array();
+   for (var i = 0; i < rows.length; i++)
+   msgIds.push(rows[i].substr(4));
 
-  return msgIds;
+   return msgIds;
 }
 
 function configureMessageListEvents() {
-  var messageList = $("messageList");
-  if (messageList) {
-    messageList.addEventListener("selectionchange",
-                                 onMessageSelectionChange, false);
-    var rows = messageList.tBodies[0].rows;
-    var start = 0;
-    if (rows.length > 1) {
-      while (rows[start].cells[0].hasClassName("tbtv_headercell")
-             || rows[start].cells[0].hasClassName("tbtv_navcell"))
-        start++;
-      for (var i = start; i < rows.length; i++) {
-        rows[i].addEventListener("mousedown", onRowClick, false);
-        rows[i].addEventListener("contextmenu", onMessageContextMenu, false);
-        
-        rows[i].dndTypes = function() { return new Array("mailRow"); };
-        rows[i].dndGhost = messageListGhost;
-        rows[i].dndDataForType = messageListData;
-        document.DNDManager.registerSource(rows[i]);
-        
-        for (var j = 0; j < rows[i].cells.length; j++) {
-          var cell = rows[i].cells[j];
-          cell.addEventListener("mousedown", listRowMouseDownHandler, false);
-          if (j == 2 || j == 3 || j == 5)
-            cell.addEventListener("dblclick", onMessageDoubleClick, false);
-          else if (j == 4) {
-            var img = cell.childNodesWithTag("img")[0];
-            img.addEventListener("click", mailListMarkMessage, false);
-          }
-        }
+   var messageList = $("messageList");
+   if (messageList) {
+      Event.observe(messageList, "selectionchange", onMessageSelectionChange);
+      var rows = messageList.tBodies[0].rows;
+      var start = 0;
+      if (rows.length > 1) {
+        while (rows[start].cells[0].hasClassName("tbtv_headercell")
+               || rows[start].cells[0].hasClassName("tbtv_navcell"))
+           start++;
+        for (var i = start; i < rows.length; i++) {
+           Event.observe(rows[i], "mousedown", onRowClick);
+           Event.observe(rows[i], "contextmenu", onMessageContextMenu);
+           
+           rows[i].dndTypes = function() { return new Array("mailRow"); };
+           rows[i].dndGhost = messageListGhost;
+           rows[i].dndDataForType = messageListData;
+           document.DNDManager.registerSource(rows[i]);
+           
+           for (var j = 0; j < rows[i].cells.length; j++) {
+              var cell = rows[i].cells[j];
+              Event.observe(cell, "mousedown", listRowMouseDownHandler);
+              if (j == 2 || j == 3 || j == 5)
+                 Event.observe(cell, "dblclick", onMessageDoubleClick);
+              else if (j == 4) {
+                 var img = cell.childNodesWithTag("img")[0];
+                 Event.observe(img, "click", mailListMarkMessage);
+              }
+           }
+        }
       }
-    }
-  }
+   }
 }
 
 function configureDragHandles() {
-  var handle = $("verticalDragHandle");
-  if (handle) {
-    handle.addInterface(SOGoDragHandlesInterface);
-    handle.leftBlock=$("leftPanel");
-    handle.rightBlock=$("rightPanel");
-  }
+   var handle = $("verticalDragHandle");
+   if (handle) {
+      handle.addInterface(SOGoDragHandlesInterface);
+      handle.leftBlock=$("leftPanel");
+      handle.rightBlock=$("rightPanel");
+   }
 
-  handle = $("rightDragHandle");
-  if (handle) {
-    handle.addInterface(SOGoDragHandlesInterface);
-    handle.upperBlock=$("mailboxContent");
-    handle.lowerBlock=$("messageContent");
-  }
+   handle = $("rightDragHandle");
+   if (handle) {
+      handle.addInterface(SOGoDragHandlesInterface);
+      handle.upperBlock=$("mailboxContent");
+      handle.lowerBlock=$("messageContent");
+   }
 }
 
 /* dnd */
 function initDnd() {
-//   log ("MailerUI initDnd");
-
-  var tree = $("d");
-  if (tree) {
-    var images = tree.getElementsByTagName("img");
-    for (var i = 0; i < images.length; i++) {
-      if (images[i].id[0] == 'j') {
-        images[i].dndAcceptType = mailboxSpanAcceptType;
-        images[i].dndEnter = plusSignEnter;
-        images[i].dndExit = plusSignExit;
-        document.DNDManager.registerDestination(images[i]);
+   //   log ("MailerUI initDnd");
+
+   var tree = $("d");
+   if (tree) {
+      var images = tree.getElementsByTagName("img");
+      for (var i = 0; i < images.length; i++) {
+        if (images[i].id[0] == 'j') {
+           images[i].dndAcceptType = mailboxSpanAcceptType;
+           images[i].dndEnter = plusSignEnter;
+           images[i].dndExit = plusSignExit;
+           document.DNDManager.registerDestination(images[i]);
+        }
+      }
+      var nodes = document.getElementsByClassName("nodeName", tree);
+      for (var i = 0; i < nodes.length; i++) {
+        nodes[i].dndAcceptType = mailboxSpanAcceptType;
+        nodes[i].dndEnter = mailboxSpanEnter;
+        nodes[i].dndExit = mailboxSpanExit;
+        nodes[i].dndDrop = mailboxSpanDrop;
+        document.DNDManager.registerDestination(nodes[i]);
       }
-    }
-    var nodes = document.getElementsByClassName("nodeName", tree);
-    for (var i = 0; i < nodes.length; i++) {
-      nodes[i].dndAcceptType = mailboxSpanAcceptType;
-      nodes[i].dndEnter = mailboxSpanEnter;
-      nodes[i].dndExit = mailboxSpanExit;
-      nodes[i].dndDrop = mailboxSpanDrop;
-      document.DNDManager.registerDestination(nodes[i]);
-    }
-  }
+   }
 }
 
 /* stub */
@@ -1009,66 +1018,91 @@ function refreshContacts() {
 }
 
 function openInbox(node) {
-  var done = false;
-  openMailbox(node.parentNode.getAttribute("dataname"));
-  var tree = $("d");
-  tree.selectedEntry = node;
-  node.select();
-  var currentNode = node.parentNode.parentNode;
-  while (!done) {
-    var number = currentNode.getAttribute("id").substr(2);
-    d.o(number);
-    if (number == "1")
-      done = true;
-    else
-      currentNode = currentNode.parentNode;
-  }
+   var done = false;
+   openMailbox(node.parentNode.getAttribute("dataname"));
+   var tree = $("d");
+   tree.selectedEntry = node;
+   node.select();
+   var currentNode = node.parentNode.parentNode;
+   while (!done) {
+      var number = currentNode.getAttribute("id").substr(2);
+      d.o(number);
+      if (number == "1")
+        done = true;
+      else
+        currentNode = currentNode.parentNode;
+   }
 }
 
 function configureSearchField() {
    var searchValue = $("searchValue");
 
-   searchValue.addEventListener("mousedown", onSearchMouseDown, false);
-   searchValue.addEventListener("click", popupSearchMenu, false);
-   searchValue.addEventListener("blur", onSearchBlur, false);
-   searchValue.addEventListener("focus", onSearchFocus, false);
-   searchValue.addEventListener("keydown", onSearchKeyDown, false);
-}
-
-var initMailer = {
-   handleEvent: function (event) {
-      if (!document.body.hasClassName("popup")) {
-        configureSearchField();
-        var inboxFound = false;
-        configureMessageListEvents();
-        initDnd();
-        var tree = $("d");
-        var nodes = document.getElementsByClassName("node", tree);
-        for (i = 0; i < nodes.length; i++) {
-           nodes[i].addEventListener("click", onMailboxTreeItemClick, false);
-           nodes[i].addEventListener("contextmenu", onFolderMenuClick, false);
-           if (!inboxFound
-               && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
-              openInbox(nodes[i]);
-              inboxFound = true;
-           }
+   Event.observe(searchValue, "mousedown", onSearchMouseDown);
+   Event.observe(searchValue, "click", popupSearchMenu);
+   Event.observe(searchValue, "blur", onSearchBlur);
+   Event.observe(searchValue, "focus", onSearchFocus);
+   Event.observe(searchValue, "keydown", onSearchKeyDown);
+}
+
+function initMailer(event) {
+   if (!document.body.hasClassName("popup")) {
+      configureSearchField();
+      var inboxFound = false;
+      configureMessageListEvents();
+      initDnd();
+      var tree = $("d");
+      var nodes = document.getElementsByClassName("node", tree);
+      for (i = 0; i < nodes.length; i++) {
+        Event.observe(nodes[i], "click", onMailboxTreeItemClick);
+        Event.observe(nodes[i], "contextmenu", onFolderMenuClick);
+        if (!inboxFound
+            && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
+           openInbox(nodes[i]);
+           inboxFound = true;
         }
       }
-      
-      /*
-      , 'onMailboxTreeItemClick(this);'
-      <!--      if (typeof(node.datatype) != "undefined") str += ' oncontextmenu="onFolderMenuClick(event, this);"';
-      
-      */
    }
 }
 
 function initializeMenus() {
-  var menus = new Array("accountIconMenu", "inboxIconMenu", "trashIconMenu",
-                        "mailboxIconMenu", "addressMenu", "messageListMenu",
-                        "messageContentMenu", "label-menu", "mailboxes-menu",
-                        "mark-menu", "searchMenu");
-  initMenusNamed(menus);
-}
-
-window.addEventListener("load", initMailer, false);
+   menus["menuIds"] = new Array("accountIconMenu", "inboxIconMenu",
+                               "trashIconMenu", "mailboxIconMenu",
+                               "addressMenu", "messageListMenu",
+                               "messageContentMenu", "label-menu",
+                               "mark-menu");
+   menus["accountIconMenu"] = new Array(null, null, null, null, null, null,
+                                       null, null, null, onMenuSharing);
+   menus["inboxIconMenu"] = new Array(null, null, null, "-", null, null,
+                                     null, "-", null, onMenuSharing);
+   menus["trashIconMenu"] = new Array(null, null, null, "-", null, null, null,
+                                     null, "-", null, onMenuSharing);
+   menus["mailboxIconMenu"] = new Array(null, null, null, "-", null, null,
+                                       null, null, null, "-", null,
+                                       onMenuSharing);
+   menus["addressMenu"] = new Array(newContactFromEmail, newEmailTo, null);
+   menus["messageListMenu"] = new Array(onMenuOpenMessage, "-",
+                                       onMenuReplyToSender,
+                                       onMenuReplyToAll,
+                                       onMenuForwardMessage, null,
+                                       "-", "mailboxes-menu",
+                                       "mailboxes-menu", "label-menu",
+                                       "mark-menu", "-", null, null,
+                                       null, onMenuDeleteMessage);
+   menus["messageContentMenu"] = new Array(onMenuReplyToSender,
+                                          onMenuReplyToAll,
+                                          onMenuForwardMessage,
+                                          null,
+                                          "mailboxes-menu",
+                                          "mailboxes-menu",
+                                          "-", "label-menu", "mark-menu",
+                                           "-", null, null, null,
+                                          onMenuDeleteMessage);
+   menus["label-menu"] = new Array(null, "-", null , null, null, null , null,
+                                  null);
+   menus["mark-menu"] = new Array(null, null, null, null, "-", null, "-",
+                                 null, null, null);
+
+   initMenus();
+}
+
+Event.observe(window, "load", initMailer);
index 718df0f35153918e006a7a6465bc48a891768dbe..4c902a36923f954277328916a4660f1e0d6d0e1c 100644 (file)
@@ -23,28 +23,36 @@ var usersRightsWindowHeight = 250;
 var usersRightsWindowWidth = 502;
 
 function newEvent(sender, type) {
-  var day = sender.getAttribute("day");
-  if (!day)
-    day = currentDay;
-
-  var user = UserLogin;
-  if (sender.parentNode.getAttribute("id") != "toolbar"
-      && currentView == "multicolumndayview" && type == "event")
-     user = sender.parentNode.parentNode.getAttribute("user");
-
-  var hour = sender.getAttribute("hour");
-  var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type;
-  var params = new Array();
-  if (day)
-    params.push("day=" + day);
-  if (hour)
-    params.push("hm=" + hour);
-  if (params.length > 0)
-    urlstr += "?" + params.join("&");
+   var day = sender.getAttribute("day");
+   if (!day)
+      day = currentDay;
+
+   var user = UserLogin;
+   if (sender.parentNode.getAttribute("id") != "toolbar"
+       && currentView == "multicolumndayview" && type == "event")
+      user = sender.parentNode.parentNode.getAttribute("user");
+
+   var hour = sender.getAttribute("hour");
+   var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type;
+   var params = new Array();
+   if (day)
+      params.push("day=" + day);
+   if (hour)
+      params.push("hm=" + hour);
+   if (params.length > 0)
+      urlstr += "?" + params.join("&");
+   
+   window.open(urlstr, "", "width=490,height=470,resizable=0");
+   
+   return false; /* stop following the link */
+}
 
-  window.open(urlstr, "", "width=490,height=470,resizable=0");
+function onMenuNewEventClick(event) {
+   newEvent(this, "event");
+}
 
-  return false; /* stop following the link */
+function onMenuNewTaskClick(event) {
+   newEvent(this, "task");
 }
 
 function _editEventId(id, owner) {
@@ -552,7 +560,7 @@ function onAppointmentContextMenu(event, element) {
   var menu = $("appointmentsListMenu");
 
   menu.addEventListener("hideMenu", onAppointmentContextMenuHide, false);
-  onMenuClick(event, "appointmentsListMenu");
+  popupMenu(event, "appointmentsListMenu", element);
 
   var topNode = $("appointmentsList");
   var selectedNodes = topNode.getSelectedRows();
@@ -717,22 +725,20 @@ function popupMonthMenu(event, menuId) {
   }
 }
 
-function onMonthMenuItemClick(node) {
-  var month = '' + node.getAttribute("month");
+function onMonthMenuItemClick(event) {
+  var month = '' + this.getAttribute("month");
   var year = '' + $("yearLabel").innerHTML;
-  
-  changeDateSelectorDisplay(year+month+"01", true);
 
-  return false;
+  changeDateSelectorDisplay(year + month + "01", true);
+
+//   event.cancelBubble();
 }
 
-function onYearMenuItemClick(node) {
+function onYearMenuItemClick(event) {
   var month = '' + $("monthLabel").getAttribute("month");;
-  var year = '' + node.innerHTML;
+  var year = '' + this.innerHTML;
 
-  changeDateSelectorDisplay(year+month+"01", true);
-
-  return false;
+  changeDateSelectorDisplay(year + month + "01", true);
 }
 
 function onSearchFormSubmit() {
@@ -980,25 +986,46 @@ function browseURL(anchor, event) {
 }
 
 function initializeMenus() {
-  var menus = new Array("monthListMenu", "yearListMenu",
-                        "appointmentsListMenu", "calendarsMenu", "searchMenu");
-  initMenusNamed(menus);
-
-  $("calendarSelector").attachMenu("calendarsMenu");
-
-  var accessRightsMenuEntry = $("accessRightsMenuEntry");
-  accessRightsMenuEntry.addEventListener("mouseup",
-                                         onAccessRightsMenuEntryMouseUp,
-                                         false);
-}
-
-function onAccessRightsMenuEntryMouseUp(event) {
+   menus["menuIds"] = new Array("monthListMenu", "yearListMenu",
+                               "appointmentsListMenu",
+                               "calendarsMenu",
+                               "searchMenu");
+   var dateMenu = new Array();
+   for (var i = 0; i < 12; i++)
+      dateMenu.push(onMonthMenuItemClick);
+   menus["monthListMenu"] = dateMenu;
+
+   dateMenu = new Array();
+   for (var i = 0; i < 11; i++)
+      dateMenu.push(onYearMenuItemClick);
+   menus["yearListMenu"] = dateMenu;
+
+   menus["appointmentsListMenu"] = new Array(onMenuNewEventClick, "-",
+                                            onMenuNewTaskClick,
+                                            editEvent, deleteEvent, "-",
+                                            onSelectAll, "-",
+                                            null, null);
+   menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
+                                     null, "-", onMenuSharing);
+   menus["searchMenu"] = new Array(setSearchCriteria);
+
+   initMenus();
+   var selector = $("calendarSelector");
+   if (selector)
+      selector.attachMenu("calendarsMenu");
+}
+
+function onMenuSharing(event) {
   var folders = $("calendarList");
   var selected = folders.getSelectedNodes()[0];
-  var folderID = selected.getAttribute("id");
-  var urlstr = URLForFolderID(folderID) + "/acls";
+  /* FIXME: activation of the context menu should preferable select the entry
+              above which the event has occured */
+  if (selected) {
+     var folderID = selected.getAttribute("id");
+     var urlstr = URLForFolderID(folderID) + "/acls";
 
-  openAclWindow(urlstr);
+     openAclWindow(urlstr);
+  }
 }
 
 function configureDragHandles() {
index 74845b325c2fdfddbb2c63669ab9fc27151e05de..5354d999859c0071515166255900d45976c366ed 100644 (file)
@@ -119,15 +119,20 @@ function onOpenUserRights(event) {
 
 function onAclLoadHandler() {
    defaultUserID = $("defaultUserID").value;
-   Event.observe($("defaultRolesBtn"), "click", openRightsForDefaultUser);
+   var defaultRolesBtn = $("defaultRolesBtn");
+   if (defaultRolesBtn)
+      Event.observe(defaultRolesBtn, "click", openRightsForDefaultUser);
    var ul = $("userList");
    var lis = ul.childNodesWithTag("li");
    for (var i = 0; i < lis.length; i++)
       setEventsOnUserNode(lis[i]);
 
-   var buttons = $("userSelectorButtons").childNodesWithTag("a");
-   Event.observe(buttons[0], "click", onUserAdd);
-   Event.observe(buttons[1], "click", onUserRemove);
+   var buttonArea = $("userSelectorButtons");
+   if (buttonArea) {
+      var buttons = buttonArea.childNodesWithTag("a");
+      Event.observe(buttons[0], "click", onUserAdd);
+      Event.observe(buttons[1], "click", onUserRemove);
+   }
 
    this.userRightsHeight = window.opener.getUsersRightsWindowHeight();
    this.userRightsWidth = window.opener.getUsersRightsWindowWidth();
diff --git a/UI/WebServerResources/UIxMailUserRightsEditor.css b/UI/WebServerResources/UIxMailUserRightsEditor.css
new file mode 100644 (file)
index 0000000..eaea573
--- /dev/null
@@ -0,0 +1,49 @@
+DIV.title
+{ color: #000;
+  vertical-align: bottom;
+  padding-top: 15px;
+  padding-left: 1em;
+  height: 33px;
+  background-color: #fff;
+  border-bottom: 1px solid #555; }
+
+DIV.title SPAN.value
+{ margin-left: 1em;
+  font-size: 18px;
+  font-weight: bold; }
+
+DIV.calendarUserRights
+{ margin: 1em;}
+
+DIV.calendarUserRights > TABLE
+{ background-color: #fff;
+  width: 45em;
+  color: #999;
+  border-collapse: collapse;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  -moz-border-top-colors: #9c9a94 #000 transparent;
+  -moz-border-left-colors: #9c9a94 #000 transparent; }
+
+DIV.calendarUserRights > TABLE TR.permissions TH
+{ color: #00f;
+/*   background-color: #ddd;
+ */  border-bottom: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TH
+{ width: 15em; }
+
+DIV.calendarUserRights > TABLE TD.eventType
+{ width: 5em;
+  text-align: right;
+  border-right: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TD
+{ text-align: center;
+  border-top: 1px solid #cecbff; }
+
+DIV.buttons
+{ text-align: right;
+  margin: 1em; }
diff --git a/UI/WebServerResources/UIxMailUserRightsEditor.js b/UI/WebServerResources/UIxMailUserRightsEditor.js
new file mode 100644 (file)
index 0000000..71fe311
--- /dev/null
@@ -0,0 +1,9 @@
+function onCancelClick(event) {
+   window.close();
+}
+
+function initACLButtons() {
+   $("cancelButton").addEventListener("click", onCancelClick, false);
+}
+
+window.addEventListener("load", initACLButtons, false);
index a15911de11f075bedcd1c8e79afdc02b68afdc9e..19c19b1af5f1468710684f470b47790b59b29119 100644 (file)
@@ -218,8 +218,6 @@ DIV#toolbar
   white-space: nowrap;
   overflow: auto; }
 
-BODY.popup { min-width: 400px; }
-
 BODY.popup DIV#toolbar
 { border-top: 0px; }
 
index 97385980d9073ac7b8cd3a164903930434fe399c..7943f2f2a14630690e2e00072de2da8c8c20e553 100644 (file)
@@ -20,8 +20,6 @@
 */
 /* some generic JavaScript code for SOGo */
 
-// TODO: replace things with Prototype where applicable
-
 /* generic stuff */
 
 var logConsole;
@@ -30,6 +28,7 @@ var logWindow = null;
 var queryParameters;
 
 var activeAjaxRequests = 0;
+var menus = new Array();
 
 // logArea = null;
 var allDocumentElements = null;
@@ -411,7 +410,8 @@ function onRowClick(event) {
 
   if (startSelection != node.parentNode.getSelectedNodes()) {
     var parentNode = node.parentNode;
-    if (parentNode instanceof HTMLTableSectionElement)
+    log("onRowClick " + parentNode.tagName);
+    if (parentNode.tagName == 'TBODY')
       parentNode = parentNode.parentNode;
     var onSelectionChangeEvent = document.createEvent("UIEvents");
     onSelectionChangeEvent.initEvent("selectionchange", true, true);
@@ -424,47 +424,37 @@ function onRowClick(event) {
 var bodyOnClick = "";
 // var acceptClick = false;
 
-function onMenuClick(event, menuId) {
-  var node = event.target;
-
-  if (document.currentPopupMenu)
-    hideMenu(event, document.currentPopupMenu);
+function popupMenu(event, menuId, target) {
+   document.menuTarget = target;
 
-  var popup = document.getElementById(menuId);
+   if (document.currentPopupMenu)
+      hideMenu(event, document.currentPopupMenu);
 
-  var menuTop = event.pageY;
-  var menuLeft = event.pageX;
-  var heightDiff = (window.innerHeight
-                   - (menuTop + popup.offsetHeight));
-  if (heightDiff < 0)
-    menuTop += heightDiff;
+   var popup = document.getElementById(menuId);
 
-  var leftDiff = (window.innerWidth
-                 - (menuLeft + popup.offsetWidth));
-  if (leftDiff < 0)
-    menuLeft -= popup.offsetWidth;
+   var menuTop = event.pageY;
+   var menuLeft = event.pageX;
+   var heightDiff = (window.innerHeight
+                    - (menuTop + popup.offsetHeight));
+   if (heightDiff < 0)
+      menuTop += heightDiff;
+  
+   var leftDiff = (window.innerWidth
+                  - (menuLeft + popup.offsetWidth));
+   if (leftDiff < 0)
+      menuLeft -= popup.offsetWidth;
 
-  popup.style.top = menuTop + "px;";
-  popup.style.left = menuLeft + "px;";
-  popup.style.visibility = "visible;";
-  setupMenuTarget(popup, node);
+   popup.style.top = menuTop + "px;";
+   popup.style.left = menuLeft + "px;";
+   popup.style.visibility = "visible;";
 
-  bodyOnClick = "" + document.body.getAttribute("onclick");
-  document.body.setAttribute("onclick", "onBodyClick(event);");
-  document.currentPopupMenu = popup;
+   bodyOnClick = "" + document.body.getAttribute("onclick");
+   document.body.setAttribute("onclick", "onBodyClick(event);");
+   document.currentPopupMenu = popup;
 
-  event.cancelBubble = true;
-  event.returnValue = false;
-
-  return false;
-}
-
-function setupMenuTarget(menu, target) {
-  menu.menuTarget = target;
-  var menus = document.getElementsByClassName("menu", menu);
-  for (var i = 0; i < menus.length; i++) {
-    menus[i].menuTarget = target;
-  }
+   event.cancelBubble = true;
+   event.returnValue = false;
+   event.preventDefault();
 }
 
 function getParentMenu(node) {
@@ -485,11 +475,11 @@ function getParentMenu(node) {
 }
 
 function onBodyClick(event) {
-  document.currentPopupMenu.menuTarget = null;
-  hideMenu(event, document.currentPopupMenu);
-  document.body.setAttribute("onclick", bodyOnClick);
-
-  return false;
+   document.body.menuTarget = null;
+   hideMenu(event, document.currentPopupMenu);
+   document.body.setAttribute("onclick", bodyOnClick);
+   
+   return false;
 }
 
 function hideMenu(event, menuNode) {
@@ -516,7 +506,7 @@ function hideMenu(event, menuNode) {
   menuNode.dispatchEvent(onhideEvent);
 }
 
-function onMenuEntryClick(event, menuId) {
+function onMenuEntryClick(event) {
   var node = event.target;
 
   id = getParentMenu(node).menuTarget;
@@ -543,10 +533,10 @@ function parseQueryParameters(url) {
 function initLogConsole() {
   var logConsole = $("logConsole");
   if (logConsole) {
-    logConsole.addEventListener("dblclick", onLogDblClick, false);
+    Event.observe(logConsole, "dblclick", onLogDblClick, false);
     logConsole.innerHTML = "";
     node = document.getElementsByTagName('body')[0];
-    node.addEventListener("keydown", onBodyKeyDown, true);
+    Event.observe(node, "keydown", onBodyKeyDown, true);
   }
 }
 
@@ -567,9 +557,9 @@ function toggleLogConsole(event) {
   var logConsole = $("logConsole");
   var display = '' + logConsole.style.display;
   if (display.length == 0) {
-    logConsole.style.display = 'block;';
+    logConsole.setStyle({ display: 'block' });
   } else {
-    logConsole.style.display = '';
+    logConsole.setStyle({ display: '' });
   }
   event.cancelBubble = true;
   event.returnValue = false;
@@ -584,7 +574,7 @@ function log(message) {
   }
   var logConsole = logWindow.document.getElementById("logConsole");
   if (logConsole)
-    logConsole.innerHTML += message.replace("<", "&lt;") + '<br />' + "\n";
+    logConsole.innerHTML += message.replace("<", "&lt;", "g") + '<br />' + "\n";
 }
 
 function backtrace() {
@@ -611,10 +601,9 @@ function backtrace() {
 }
 
 function dropDownSubmenu(event) {
-  var node = event.target;
-  var submenu = node.getAttribute("submenu");
-  if (submenu && submenu != "") {
-    var submenuNode = document.getElementById(submenu);
+  var node = this;
+  if (this.submenu && this.submenu != "") {
+    var submenuNode = document.getElementById(this.submenu);
     var parentNode = getParentMenu(node);
     if (parentNode.submenu)
       hideMenu(event, parentNode.submenu);
@@ -634,7 +623,7 @@ function dropDownSubmenu(event) {
     if (window.innerWidth
         < (menuLeft + submenuNode.offsetWidth
            + parentNode.cascadeLeftOffset()))
-       menuLeft = -submenuNode.offsetWidth + 3;
+       menuLeft = - submenuNode.offsetWidth + 3;
     
     parentNode.setAttribute('onmousemove', 'checkDropDown(event);');
     node.setAttribute('class', 'submenu-selected');
@@ -695,10 +684,9 @@ function popupSearchMenu(event) {
 function setSearchCriteria(event) {
   searchValue = $("searchValue");
   searchCriteria = $("searchCriteria");
-  
-  var node = event.target;
-  searchValue.setAttribute("ghost-phrase", node.innerHTML);
-  searchCriteria = node.getAttribute('id');
+
+  searchValue.setAttribute("ghost-phrase", this.innerHTML);
+//   searchCriteria = this.getAttribute('id');
 }
 
 function checkSearchValue(event) {
@@ -767,7 +755,12 @@ function initCriteria() {
  
   var searchOptions = $("searchOptions");
   if (searchOptions) {
-    firstOption = searchOptions.childNodes[1];
+    var firstOption;
+    $A(searchOptions.childNodes).each(function (item) {
+      if (item.tagName == 'LI') {
+       firstOption = item;
+      }
+    });
     searchCriteria.value = firstOption.getAttribute('id');
     searchValue.setAttribute('ghost-phrase', firstOption.innerHTML);
     if (searchValue.value == '') {
@@ -893,12 +886,12 @@ function initTabs() {
 
     var firstTab;
     for (var i = 0; i < nodes.length; i++) {
-      if (nodes[i] instanceof HTMLLIElement) {
-        if (!firstTab) {
+      if (nodes[i].tagName == 'LI') {
+       if (!firstTab) {
           firstTab = i;
         }
-        nodes[i].addEventListener("mousedown", onTabMouseDown, true);
-        nodes[i].addEventListener("click", onTabClick, true);
+        Event.observe(nodes[i], "mousedown", onTabMouseDown, true);
+       Event.observe(nodes[i], "click", onTabClick, true);
       }
     }
 
@@ -911,23 +904,38 @@ function initTabs() {
   }
 }
 
-function initMenusNamed(menuDivNames) {
-  for (var i = 0; i < menuDivNames.length; i++) {
-    var menuDIV = $(menuDivNames[i]);
-    if (menuDIV)
-      initMenu(menuDIV);
-    else
-      log("menu named '" + menuDivNames[i] + "' not found");
-  }
+function initMenus() {
+   for (var i = 0; i < menus["menuIds"].length; i++) {
+      var menuId = menus["menuIds"][i];
+      var callbacks = menus[menuId];
+      var menuDIV = $(menuId);
+      if (menuDIV)
+        initMenu(menuDIV, callbacks);
+   }
 }
 
-function initMenu(menuDIV) {
-  var lis = menuDIV.childNodesWithTag("ul")[0].childNodesWithTag("li");
-  for (var j = 0; j < lis.length; j++)
-    lis[j].addEventListener("mousedown", listRowMouseDownHandler, false);
-  var subMenus = menuDIV.childNodesWithTag("div");
-  for (var i = 0; i < subMenus.length; i++)
-    initMenu(subMenus[i]);
+function initMenu(menuDIV, callbacks) {
+   var lis = $(menuDIV.childNodesWithTag("ul")[0]).childNodesWithTag("li");
+   for (var j = 0; j < lis.length; j++) {
+      var node = lis[j];
+      Event.observe(node, "mousedown", listRowMouseDownHandler, false);
+      var callback = callbacks[j];
+      if (callback) {
+        if (typeof(callback) == "string") {
+           if (callback == "-")
+              node.addClassName("separator");
+           else {
+              node.submenu = callback;
+              node.addClassName("submenu");
+              Event.observe(node, "mouseover", dropDownSubmenu);
+           }
+        }
+        else
+           Event.observe(node, "mouseup", callback);
+      }
+      else
+        node.addClassName("disabled");
+   }
 }
 
 function onTabMouseDown(event) {
@@ -1071,9 +1079,9 @@ var onLoadHandler = function (event) {
   queryParameters = parseQueryParameters('' + window.location);
   if (!document.body.hasClassName("popup")) {
     initLogConsole();
-    initializeMenus();
     initCriteria();
   }
+  initializeMenus();
   initTabs();
   configureDragHandles();
   configureSortableTableHeaders();
@@ -1090,7 +1098,7 @@ function configureSortableTableHeaders() {
     if (!anchor.link) {
       anchor.link = anchor.getAttribute("href");
       anchor.href = "#";
-      anchor.addEventListener("click", onHeaderClick, true);
+      Event.observe(anchor, "click", onHeaderClick, true);
     }
   }
 }
@@ -1105,20 +1113,15 @@ function configureLinkBanner() {
   if (linkBanner) {
     var anchors = linkBanner.childNodesWithTag("a");
     for (var i = 0; i < 2; i++) {
-      anchors[i].addEventListener("mousedown", listRowMouseDownHandler,
-                                  false);
-      anchors[i].addEventListener("click", onLinkBannerClick, false);
+       Event.observe(anchors[i], "mousedown", listRowMouseDownHandler);
+       Event.observe(anchors[i], "click", onLinkBannerClick);
     }
     if (anchors.length > 3)
-      anchors[3].addEventListener("click", toggleLogConsole, true);
+       Event.observe(anchors[3], "click", toggleLogConsole);
   }
 }
 
-if (window.addEventListener) {
-  window.addEventListener('load', onLoadHandler, false);
-} else if (document.addEventListener) {
-  document.addEventListener('load', onLoadHandler, false);
-}
+Event.observe(window, "load", onLoadHandler, false);
 
 /* stubs */
 function configureDragHandles() {