]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1288 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 5 Dec 2007 22:25:00 +0000 (22:25 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 5 Dec 2007 22:25:00 +0000 (22:25 +0000)
16 files changed:
ChangeLog
Main/GNUmakefile
Main/NSException+Stacktrace.m [new file with mode: 0644]
SoObjects/Mailer/SOGoDraftObject.m
SoObjects/SOGo/SOGoUserFolder.m
UI/Contacts/UIxContactFoldersView.m
UI/Contacts/product.plist
UI/MainUI/SOGoRootPage.m
UI/MainUI/SOGoUserHomePage.m
UI/MainUI/product.plist
UI/WebServerResources/MailerUI.css
UI/WebServerResources/MailerUI.js
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxContactsUserFolders.js
UI/WebServerResources/UIxMailToSelection.js
UI/WebServerResources/generic.js

index 37b7b4aef41130f0d6f6959b9bd2a85a6c59ec20..efbbf3bf999d127b031d4f844905b15c9702607e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2007-12-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * Main/NSException+Stacktrace.m: added missing symbols from
+       NSException.m and NSDebug.m (GNUstep).
+
+       * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
+       -foldersSearchAction]): make use of the new search methods in
+       SOGoUserFolder (see below).
+
+       * UI/Contacts/UIxContactFoldersView.m ([-foldersSearchAction]):
+       moved method into ../MainUI/SOGoUserHomePage.m.
+
+       * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
+       -foldersOfType:folderTypeforUID:uid]): only return folders owned
+       by the specified user.
+
+2007-12-05  Francis Lachapelle  <flachapelle@inverse.ca>
+
+       * SoObjects/Mailer/SOGoDraftObject.m: The condition for replyToAll
+       has to be done later to avoid duplicated to and cc addresses.
+
 2007-12-04  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * SoObjects/Appointments/SOGoAppointmentFolder.m
index cac596f5de6f12624d0f977368de4142c9420510..ab489728be5ddc23bc680ecaf0d699f4e5f7dcdd 100644 (file)
@@ -5,7 +5,7 @@ include $(GNUSTEP_MAKEFILES)/common.make
 include ../Version
 include ./Version
 
-ADDITIONAL_INCLUDE_DIRS += -I../SOPE/
+ADDITIONAL_INCLUDE_DIRS += -I../SOPE/ -D_GNU_SOURCE
 ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj/ -lbfd
 
 SOGOD     = sogod-$(MAJOR_VERSION).$(MINOR_VERSION)
diff --git a/Main/NSException+Stacktrace.m b/Main/NSException+Stacktrace.m
new file mode 100644 (file)
index 0000000..c08bc21
--- /dev/null
@@ -0,0 +1,889 @@
+/** NSException - Object encapsulation of a general exception handler
+   Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
+
+   Written by:  Adam Fedor <fedor@boulder.colorado.edu>
+   Date: Mar 1995
+
+   This file is part of the GNUstep Base Library.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02111 USA.
+
+   $Date: 2007-09-14 07:36:11 -0400 (Fri, 14 Sep 2007) $ $Revision: 25482 $
+
+   NOTE: This code was taken from GNUstep Base Library and sligthly modified
+         by Ludovic Marcotte <ludovic@inverse.ca>
+*/
+
+#include <bfd.h>
+#include <dlfcn.h>
+#include <signal.h>
+
+typedef void* dl_handle_t;
+typedef void* dl_symbol_t;
+
+#import "NSException+Stacktrace.h"
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSLock.h>
+#import <Foundation/NSNull.h>
+#import <Foundation/NSProcessInfo.h>
+#import <Foundation/NSThread.h>
+
+// #if GNUSTEP_BASE_MAJOR_VERSION >= 1
+// #if GNUSTEP_BASE_MINOR_VERSION > 13
+
+//
+//
+//
+static void _terminate()
+{
+  abort();
+}
+
+static void
+_NSFoundationUncaughtExceptionHandler (NSException *exception)
+{
+  NSString     *stack;
+  
+  fprintf(stderr, "Uncaught exception %s, reason: %s\n",
+    [[exception name] lossyCString], [[exception reason] lossyCString]);
+  fflush(stderr);      /* NEEDED UNDER MINGW */
+  stack = [[[exception userInfo] objectForKey: @"GSStackTraceKey"] description];
+  if (stack != nil)
+    {
+      fprintf(stderr, "Stack\n%s\n", [stack lossyCString]);
+    }
+  fflush(stderr);      /* NEEDED UNDER MINGW */
+
+  _terminate();
+}
+
+//
+//
+//
+
+#define        STACKSYMBOLS    1
+
+@interface GSStackTrace : NSObject
+{
+  NSMutableArray *frames;
+}
+
++ (GSStackTrace*) currentStack;
+
+- (NSString*) description;
+- (NSEnumerator*) enumerator;
+- (id) frameAt: (unsigned)index;
+- (unsigned) frameCount;
+- (NSEnumerator*) reverseEnumerator;
+
+@end
+
+#ifdef STACKSYMBOLS
+
+// GSStackTrace inspired by  FYStackTrace.m
+// created by Wim Oudshoorn on Mon 11-Apr-2006
+// reworked by Lloyd Dupont @ NovaMind.com  on 4-May-2006
+
+@class GSBinaryFileInfo;
+
+@interface GSFunctionInfo : NSObject
+{
+  void                 *_address;
+  NSString             *_fileName;
+  NSString             *_functionName;
+  int                  _lineNo;
+  GSBinaryFileInfo     *_module;
+}
+- (void*) address;
+- (NSString *) fileName;
+- (NSString *) function;
+- (id) initWithModule: (GSBinaryFileInfo*)module
+             address: (void*)address 
+                file: (NSString*)file 
+            function: (NSString*)function 
+                line: (int)lineNo;
+- (int) lineNumber;
+- (GSBinaryFileInfo*) module;
+
+@end
+
+
+@interface GSBinaryFileInfo : NSObject
+{
+  NSString     *_fileName;
+  bfd          *_abfd;
+  asymbol      **_symbols;
+  long         _symbolCount;
+}
+- (NSString *) fileName;
+- (GSFunctionInfo *) functionForAddress: (void*) address;
+- (id) initWithBinaryFile: (NSString *)fileName;
+- (id) init; // return info for the current executing process
+
+@end
+
+@implementation GSFunctionInfo
+
+- (void*) address
+{
+  return _address;
+}
+
+- (oneway void) dealloc
+{
+  [_module release];
+  _module = nil;
+  [_fileName release];
+  _fileName = nil;
+  [_functionName release];
+  _functionName = nil;
+  [super dealloc];
+}
+
+- (NSString *) description
+{
+  return [NSString stringWithFormat: @"(%@: %p) %@  %@: %d",
+    [_module fileName], _address, _functionName, _fileName, _lineNo];
+}
+
+- (NSString *) fileName
+{
+  return _fileName;
+}
+
+- (NSString *) function
+{
+  return _functionName;
+}
+
+- (id) init
+{
+  [self release];
+  return nil;
+}
+
+- (id) initWithModule: (GSBinaryFileInfo*)module
+             address: (void*)address 
+                file: (NSString*)file 
+            function: (NSString*)function 
+                line: (int)lineNo
+{
+  _module = [module retain];
+  _address = address;
+  _fileName = [file retain];
+  _functionName = [function retain];
+  _lineNo = lineNo;
+
+  return self;
+}
+
+- (int) lineNumber
+{
+  return _lineNo;
+}
+
+- (GSBinaryFileInfo *) module
+{
+  return _module;
+}
+
+@end
+
+@implementation GSBinaryFileInfo
+
++ (GSBinaryFileInfo*) infoWithBinaryFile: (NSString *)fileName
+{
+  return [[[self alloc] initWithBinaryFile: fileName] autorelease];
+}
+
++ (void) initialize
+{
+  static BOOL first = YES;
+
+  if (first == NO)
+    {
+      return;
+    }
+  first = NO;
+  bfd_init ();
+}
+
+- (oneway void) dealloc
+{
+  [_fileName release];
+  _fileName = nil;
+  if (_abfd)
+    {
+      bfd_close (_abfd);
+      _abfd = NULL;
+    }
+  if (_symbols)
+    {
+      objc_free (_symbols);
+      _symbols = NULL;
+    }
+  [super dealloc];
+}
+
+- (NSString *) fileName
+{
+  return _fileName;
+}
+
+- (id) init
+{
+  NSString *processName;
+
+  processName = [[[NSProcessInfo processInfo] arguments] objectAtIndex: 0];
+  return [self initWithBinaryFile: processName];
+}
+
+- (id) initWithBinaryFile: (NSString *)fileName
+{
+  int neededSpace;
+
+  // 1st initialize the bfd
+  if ([fileName length] == 0)
+    {
+      //NSLog (@"GSBinaryFileInfo: No File");
+      [self release];
+      return nil;
+    }
+  _fileName = [fileName copy];
+  _abfd = bfd_openr ([fileName cString], NULL);
+  if (!_abfd)
+    {
+      //NSLog (@"GSBinaryFileInfo: No Binary Info");
+      [self release];
+      return nil;
+    }
+  if (!bfd_check_format_matches (_abfd, bfd_object, NULL))
+    {
+      //NSLog (@"GSBinaryFileInfo: BFD format object error");
+      [self release];
+      return nil;
+    }
+
+  // second read the symbols from it
+  if (!(bfd_get_file_flags (_abfd) & HAS_SYMS))
+    {
+      //NSLog (@"GSBinaryFileInfo: BFD does not contain any symbols");
+      [self release];
+      return nil;
+    }
+
+  neededSpace = bfd_get_symtab_upper_bound (_abfd);
+  if (neededSpace < 0)
+    {
+      //NSLog (@"GSBinaryFileInfo: BFD error while deducing needed space");
+      [self release];
+      return nil;
+    }
+  if (neededSpace == 0)
+    {
+      //NSLog (@"GSBinaryFileInfo: BFD no space for symbols needed");
+      [self release];
+      return nil;
+    }
+  _symbols = objc_malloc (neededSpace);
+  if (!_symbols)
+    {
+      //NSLog (@"GSBinaryFileInfo: Can't allocate buffer");
+      [self release];
+      return nil;
+    }
+  _symbolCount = bfd_canonicalize_symtab (_abfd, _symbols);
+  if (_symbolCount < 0)
+    {
+      //NSLog (@"GSBinaryFileInfo: BFD error while reading symbols");
+      [self release];
+      return nil;
+    }
+
+  return self;
+}
+
+struct SearchAddressStruct
+{
+  void                 *theAddress;
+  GSBinaryFileInfo     *module;
+  asymbol              **symbols;
+  GSFunctionInfo       *theInfo;
+};
+
+static void find_address (bfd *abfd, asection *section,
+  struct SearchAddressStruct *info)
+{
+  bfd_vma      address;
+  bfd_vma      vma;
+  unsigned     size;
+  const char   *fileName;
+  const char   *functionName;
+  unsigned     line = 0;
+
+  if (info->theInfo)
+    {
+      return;
+    }
+  if (!(bfd_get_section_flags (abfd, section) & SEC_ALLOC))
+    {
+      return;
+    }
+
+  address = (bfd_vma) (intptr_t)info->theAddress;
+
+  vma = bfd_get_section_vma (abfd, section);
+
+#if     defined(bfd_get_section_size)
+  size = bfd_get_section_size (section);        // recent
+#else                                
+  size = bfd_section_size (abfd, section);      // older version
+#endif                               
+     
+  if (address < vma || address >= vma + size)
+    {
+      return;
+    }
+
+  if (bfd_find_nearest_line (abfd, section, info->symbols,
+    address - vma, &fileName, &functionName, &line))
+    {
+      GSFunctionInfo   *fi;
+      NSString         *file = nil;
+      NSString         *func = nil;
+
+      if (fileName != 0)
+        {
+         file = [NSString stringWithCString: fileName 
+           encoding: [NSString defaultCStringEncoding]];
+       }
+      if (functionName != 0)
+        {
+         func = [NSString stringWithCString: functionName 
+           encoding: [NSString defaultCStringEncoding]];
+       }
+      fi = [GSFunctionInfo alloc];
+      fi = [fi initWithModule: info->module
+                     address: info->theAddress
+                        file: file
+                    function: func
+                        line: line];
+      [fi autorelease];
+      info->theInfo = fi;
+    }
+}
+
+- (GSFunctionInfo *) functionForAddress: (void*) address
+{
+  struct SearchAddressStruct searchInfo = { address, self, _symbols, nil };
+
+  bfd_map_over_sections (_abfd,
+    (void (*) (bfd *, asection *, void *)) find_address, &searchInfo);
+  return searchInfo.theInfo;
+}
+
+@end
+
+static NSRecursiveLock         *modLock = nil;
+static NSMutableDictionary     *stackModules = nil;
+
+// initialize stack trace info
+static id
+GSLoadModule(NSString *fileName)
+{
+  GSBinaryFileInfo     *module = nil;
+
+  [modLock lock];
+
+  if (stackModules == nil)
+    {
+      NSEnumerator     *enumerator;
+      NSBundle         *bundle;
+
+      stackModules = [NSMutableDictionary new];
+
+      /*
+       * Try to ensure we have the main, base and gui library bundles.
+       */
+      [NSBundle mainBundle];
+      [NSBundle bundleForClass: [NSObject class]];
+      [NSBundle bundleForClass: NSClassFromString(@"NSView")];
+
+      /*
+       * Add file info for all bundles with code.
+       */
+      enumerator = [[NSBundle allBundles] objectEnumerator];
+      while ((bundle = [enumerator nextObject]) != nil)
+       {
+         if ([bundle load] == YES)
+           {
+             GSLoadModule([bundle executablePath]);
+           }
+       }
+    }
+
+  if ([fileName length] > 0)
+    {
+      module = [stackModules objectForKey: fileName];
+      if (module == nil);
+       {
+         module = [GSBinaryFileInfo infoWithBinaryFile: fileName];
+         if (module == nil)
+           {
+             module = (id)[NSNull null];
+           }
+         if ([stackModules objectForKey: fileName] == nil)
+           {
+             [stackModules setObject: module forKey: fileName];
+           }
+         else
+           {
+             module = [stackModules objectForKey: fileName];
+           }
+       }
+    }
+  [modLock unlock];
+
+  if (module == (id)[NSNull null])
+    {
+      module = nil;
+    }
+  return module;
+}
+
+#endif /* STACKSYMBOLS */
+
+
+//
+//
+//
+@implementation NSException (SOGoExtensions)
+
+- (void) raise
+{
+#ifndef _NATIVE_OBJC_EXCEPTIONS
+  NSThread     *thread;
+  NSHandler    *handler;
+#endif
+
+  if ([_e_info objectForKey: @"GSStackTraceKey"] == nil)
+    {
+      NSMutableDictionary      *m;
+
+      if (_e_info == nil)
+       {
+         _e_info = m = [NSMutableDictionary new];
+       }
+      else if ([_e_info isKindOfClass: [NSMutableDictionary class]] == YES)
+        {
+         m = (NSMutableDictionary*)_e_info;
+        }
+      else
+       {
+         m = [_e_info mutableCopy];
+         RELEASE(_e_info);
+         _e_info = m;
+       }
+      [m setObject: [GSStackTrace currentStack] forKey: @"GSStackTraceKey"];
+    }
+
+#ifdef _NATIVE_OBJC_EXCEPTIONS
+  @throw self;
+#else
+  thread = GSCurrentThread();
+  handler = thread->_exception_handler;
+  if (handler == NULL)
+    {
+      static   int     recursion = 0;
+
+      /*
+       * Set/check a counter to prevent recursive uncaught exceptions.
+       * Allow a little recursion in case we have different handlers
+       * being tried.
+       */
+      if (recursion++ > 3)
+       {
+         fprintf(stderr,
+           "recursion encountered handling uncaught exception\n");
+         fflush(stderr);       /* NEEDED UNDER MINGW */
+         _terminate();
+       }
+
+      /*
+       * Call the uncaught exception handler (if there is one).
+       */
+      if (_NSUncaughtExceptionHandler != NULL)
+       {
+         (*_NSUncaughtExceptionHandler)(self);
+       }
+
+      /*
+       * The uncaught exception handler which is set has not
+       * exited, so we call the builtin handler, (undocumented
+       * behavior of MacOS-X).
+       * The standard handler is guaranteed to exit/abort.
+       */
+      _NSFoundationUncaughtExceptionHandler(self);
+    }
+
+  thread->_exception_handler = handler->next;
+  handler->exception = self;
+  longjmp(handler->jumpState, 1);
+#endif
+}
+
+@end
+
+static jmp_buf *
+jbuf()
+{
+  NSMutableData        *d;
+
+  d = [[[NSThread currentThread] threadDictionary] objectForKey: @"GSjbuf"];
+  if (d == nil)
+    {
+      d = [[NSMutableData alloc] initWithLength:
+       sizeof(jmp_buf) + sizeof(void(*)(int))];
+      [[[NSThread currentThread] threadDictionary] setObject: d
+                                                     forKey: @"GSjbuf"];
+      RELEASE(d);
+    }
+  return (jmp_buf*)[d mutableBytes];
+}
+
+static void
+recover(int sig)
+{
+  jmp_buf      *env = jbuf();
+
+  longjmp(*env, 1);
+}
+
+#define _NS_FRAME_HACK(a) case a: val = __builtin_frame_address(a + 1); break;
+#define _NS_RETURN_HACK(a) case a: val = __builtin_return_address(a + 1); break;
+
+static void *
+NSFrameAddress(int offset)
+{
+  jmp_buf      *env;
+  void         (*old)(int);
+  void         *val;
+
+  env = jbuf();
+  if (setjmp(*env) == 0)
+    {
+      old = signal(SIGSEGV, recover);
+      memcpy(env + 1, &old, sizeof(old));
+      switch (offset)
+       {
+         _NS_FRAME_HACK(0); _NS_FRAME_HACK(1); _NS_FRAME_HACK(2);
+         _NS_FRAME_HACK(3); _NS_FRAME_HACK(4); _NS_FRAME_HACK(5);
+         _NS_FRAME_HACK(6); _NS_FRAME_HACK(7); _NS_FRAME_HACK(8);
+         _NS_FRAME_HACK(9); _NS_FRAME_HACK(10); _NS_FRAME_HACK(11);
+         _NS_FRAME_HACK(12); _NS_FRAME_HACK(13); _NS_FRAME_HACK(14);
+         _NS_FRAME_HACK(15); _NS_FRAME_HACK(16); _NS_FRAME_HACK(17);
+         _NS_FRAME_HACK(18); _NS_FRAME_HACK(19); _NS_FRAME_HACK(20);
+         _NS_FRAME_HACK(21); _NS_FRAME_HACK(22); _NS_FRAME_HACK(23);
+         _NS_FRAME_HACK(24); _NS_FRAME_HACK(25); _NS_FRAME_HACK(26);
+         _NS_FRAME_HACK(27); _NS_FRAME_HACK(28); _NS_FRAME_HACK(29);
+         _NS_FRAME_HACK(30); _NS_FRAME_HACK(31); _NS_FRAME_HACK(32);
+         _NS_FRAME_HACK(33); _NS_FRAME_HACK(34); _NS_FRAME_HACK(35);
+         _NS_FRAME_HACK(36); _NS_FRAME_HACK(37); _NS_FRAME_HACK(38);
+         _NS_FRAME_HACK(39); _NS_FRAME_HACK(40); _NS_FRAME_HACK(41);
+         _NS_FRAME_HACK(42); _NS_FRAME_HACK(43); _NS_FRAME_HACK(44);
+         _NS_FRAME_HACK(45); _NS_FRAME_HACK(46); _NS_FRAME_HACK(47);
+         _NS_FRAME_HACK(48); _NS_FRAME_HACK(49); _NS_FRAME_HACK(50);
+         _NS_FRAME_HACK(51); _NS_FRAME_HACK(52); _NS_FRAME_HACK(53);
+         _NS_FRAME_HACK(54); _NS_FRAME_HACK(55); _NS_FRAME_HACK(56);
+         _NS_FRAME_HACK(57); _NS_FRAME_HACK(58); _NS_FRAME_HACK(59);
+         _NS_FRAME_HACK(60); _NS_FRAME_HACK(61); _NS_FRAME_HACK(62);
+         _NS_FRAME_HACK(63); _NS_FRAME_HACK(64); _NS_FRAME_HACK(65);
+         _NS_FRAME_HACK(66); _NS_FRAME_HACK(67); _NS_FRAME_HACK(68);
+         _NS_FRAME_HACK(69); _NS_FRAME_HACK(70); _NS_FRAME_HACK(71);
+         _NS_FRAME_HACK(72); _NS_FRAME_HACK(73); _NS_FRAME_HACK(74);
+         _NS_FRAME_HACK(75); _NS_FRAME_HACK(76); _NS_FRAME_HACK(77);
+         _NS_FRAME_HACK(78); _NS_FRAME_HACK(79); _NS_FRAME_HACK(80);
+         _NS_FRAME_HACK(81); _NS_FRAME_HACK(82); _NS_FRAME_HACK(83);
+         _NS_FRAME_HACK(84); _NS_FRAME_HACK(85); _NS_FRAME_HACK(86);
+         _NS_FRAME_HACK(87); _NS_FRAME_HACK(88); _NS_FRAME_HACK(89);
+         _NS_FRAME_HACK(90); _NS_FRAME_HACK(91); _NS_FRAME_HACK(92);
+         _NS_FRAME_HACK(93); _NS_FRAME_HACK(94); _NS_FRAME_HACK(95);
+         _NS_FRAME_HACK(96); _NS_FRAME_HACK(97); _NS_FRAME_HACK(98);
+         _NS_FRAME_HACK(99);
+         default: val = NULL; break;
+       }
+      signal(SIGSEGV, old);
+    }
+  else
+    {
+      env = jbuf();
+      memcpy(&old, env + 1, sizeof(old));
+      signal(SIGSEGV, old);
+      val = NULL;
+    }
+  return val;
+}
+
+static void *
+NSReturnAddress(int offset)
+{
+  jmp_buf      *env;
+  void         (*old)(int);
+  void         *val;
+
+  env = jbuf();
+  if (setjmp(*env) == 0)
+    {
+      old = signal(SIGSEGV, recover);
+      memcpy(env + 1, &old, sizeof(old));
+      switch (offset)
+       {
+         _NS_RETURN_HACK(0); _NS_RETURN_HACK(1); _NS_RETURN_HACK(2);
+         _NS_RETURN_HACK(3); _NS_RETURN_HACK(4); _NS_RETURN_HACK(5);
+         _NS_RETURN_HACK(6); _NS_RETURN_HACK(7); _NS_RETURN_HACK(8);
+         _NS_RETURN_HACK(9); _NS_RETURN_HACK(10); _NS_RETURN_HACK(11);
+         _NS_RETURN_HACK(12); _NS_RETURN_HACK(13); _NS_RETURN_HACK(14);
+         _NS_RETURN_HACK(15); _NS_RETURN_HACK(16); _NS_RETURN_HACK(17);
+         _NS_RETURN_HACK(18); _NS_RETURN_HACK(19); _NS_RETURN_HACK(20);
+         _NS_RETURN_HACK(21); _NS_RETURN_HACK(22); _NS_RETURN_HACK(23);
+         _NS_RETURN_HACK(24); _NS_RETURN_HACK(25); _NS_RETURN_HACK(26);
+         _NS_RETURN_HACK(27); _NS_RETURN_HACK(28); _NS_RETURN_HACK(29);
+         _NS_RETURN_HACK(30); _NS_RETURN_HACK(31); _NS_RETURN_HACK(32);
+         _NS_RETURN_HACK(33); _NS_RETURN_HACK(34); _NS_RETURN_HACK(35);
+         _NS_RETURN_HACK(36); _NS_RETURN_HACK(37); _NS_RETURN_HACK(38);
+         _NS_RETURN_HACK(39); _NS_RETURN_HACK(40); _NS_RETURN_HACK(41);
+         _NS_RETURN_HACK(42); _NS_RETURN_HACK(43); _NS_RETURN_HACK(44);
+         _NS_RETURN_HACK(45); _NS_RETURN_HACK(46); _NS_RETURN_HACK(47);
+         _NS_RETURN_HACK(48); _NS_RETURN_HACK(49); _NS_RETURN_HACK(50);
+         _NS_RETURN_HACK(51); _NS_RETURN_HACK(52); _NS_RETURN_HACK(53);
+         _NS_RETURN_HACK(54); _NS_RETURN_HACK(55); _NS_RETURN_HACK(56);
+         _NS_RETURN_HACK(57); _NS_RETURN_HACK(58); _NS_RETURN_HACK(59);
+         _NS_RETURN_HACK(60); _NS_RETURN_HACK(61); _NS_RETURN_HACK(62);
+         _NS_RETURN_HACK(63); _NS_RETURN_HACK(64); _NS_RETURN_HACK(65);
+         _NS_RETURN_HACK(66); _NS_RETURN_HACK(67); _NS_RETURN_HACK(68);
+         _NS_RETURN_HACK(69); _NS_RETURN_HACK(70); _NS_RETURN_HACK(71);
+         _NS_RETURN_HACK(72); _NS_RETURN_HACK(73); _NS_RETURN_HACK(74);
+         _NS_RETURN_HACK(75); _NS_RETURN_HACK(76); _NS_RETURN_HACK(77);
+         _NS_RETURN_HACK(78); _NS_RETURN_HACK(79); _NS_RETURN_HACK(80);
+         _NS_RETURN_HACK(81); _NS_RETURN_HACK(82); _NS_RETURN_HACK(83);
+         _NS_RETURN_HACK(84); _NS_RETURN_HACK(85); _NS_RETURN_HACK(86);
+         _NS_RETURN_HACK(87); _NS_RETURN_HACK(88); _NS_RETURN_HACK(89);
+         _NS_RETURN_HACK(90); _NS_RETURN_HACK(91); _NS_RETURN_HACK(92);
+         _NS_RETURN_HACK(93); _NS_RETURN_HACK(94); _NS_RETURN_HACK(95);
+         _NS_RETURN_HACK(96); _NS_RETURN_HACK(97); _NS_RETURN_HACK(98);
+         _NS_RETURN_HACK(99);
+         default: val = NULL; break;
+       }
+      signal(SIGSEGV, old);
+    }
+  else
+    {
+      env = jbuf();
+      memcpy(&old, env + 1, sizeof(old));
+      signal(SIGSEGV, old);
+      val = NULL;
+    }
+
+  return val;
+}
+
+static unsigned NSCountFrames(void)
+{
+   unsigned    x = 0;
+
+   while (NSFrameAddress(x + 1)) x++;
+
+   return x;
+}
+
+
+static void *
+__objc_dynamic_get_symbol_path(dl_handle_t handle, dl_symbol_t symbol)
+{
+  dl_symbol_t sym;
+  Dl_info     info;
+
+  if (handle == 0)
+    handle = RTLD_DEFAULT;
+
+  sym = dlsym(handle, symbol);
+
+  if (!sym)
+    return NULL;
+
+  if (!dladdr(sym, &info))
+    return NULL;
+
+  return (void *) info.dli_fname;
+}
+
+static NSArray*
+GSListModules()
+{
+  NSArray      *result;
+
+  GSLoadModule(nil);   // initialise
+  [modLock lock];
+  result = [stackModules allValues];
+  [modLock unlock];
+  return result;
+}
+
+@implementation GSStackTrace : NSObject
+
++ (GSStackTrace*) currentStack
+{
+  return [[[GSStackTrace alloc] init] autorelease];
+}
+
+- (oneway void) dealloc
+{
+  [frames release];
+  frames = nil;
+
+  [super dealloc];
+}
+
+- (NSString*) description
+{
+  NSMutableString *result = [NSMutableString string];
+  int i;
+  int n;
+
+  n = [frames count];
+  for (i = 0; i < n; i++)
+    {
+      id       line = [frames objectAtIndex: i];
+
+      [result appendFormat: @"%3d: %@\n", i, line];
+    }
+  return result;
+}
+
+- (NSEnumerator*) enumerator
+{
+  return [frames objectEnumerator];
+}
+
+- (id) frameAt: (unsigned)index
+{
+  return [frames objectAtIndex: index];
+}
+
+- (unsigned) frameCount
+{
+  return [frames count];
+}
+
+// grab the current stack 
+- (id) init
+{
+#if    defined(STACKSYMBOLS)
+  int i;
+  int n;
+
+  frames = [[NSMutableArray alloc] init];
+  n = NSCountFrames();
+
+  for (i = 0; i < n; i++)
+    {
+      GSFunctionInfo   *aFrame = nil;
+      void             *address = NSReturnAddress(i);
+      void             *base;
+      NSString         *modulePath = __objc_dynamic_get_symbol_path(address, &base);
+      GSBinaryFileInfo *bfi;
+
+      if (modulePath != nil && (bfi = GSLoadModule(modulePath)) != nil)
+        {
+         aFrame = [bfi functionForAddress: (void*)(address - base)];
+         if (aFrame == nil)
+           {
+             /* We know we have the right module be function lookup
+              * failed ... perhaps we need to use the absolute
+              * address rather than offest by 'base' in this case.
+              */
+             aFrame = [bfi functionForAddress: address];
+           }
+//if (aFrame == nil) NSLog(@"BFI base for %@ (%p) is %p", modulePath, address, base);
+       }
+      else
+        {
+         NSArray       *modules;
+         int           j;
+         int           m;
+
+//if (modulePath != nil) NSLog(@"BFI not found for %@ (%p)", modulePath, address);
+
+         modules = GSListModules();
+         m = [modules count];
+         for (j = 0; j < m; j++)
+           {
+             bfi = [modules objectAtIndex: j];
+
+             if ((id)bfi != (id)[NSNull null])
+               {
+                 aFrame = [bfi functionForAddress: address];
+                 if (aFrame != nil)
+                   {
+                     break;
+                   }
+               }
+           }
+       }
+
+      // not found (?!), add an 'unknown' function
+      if (aFrame == nil)
+       {
+         aFrame = [GSFunctionInfo alloc];
+         [aFrame initWithModule: nil
+                        address: address 
+                           file: nil
+                       function: nil
+                           line: 0];
+         [aFrame autorelease];
+       }
+      [frames addObject: aFrame];
+    }
+#else
+  int i;
+  int n;
+
+  frames = [[NSMutableArray alloc] init];
+  n = NSCountFrames();
+
+  for (i = 0; i < n; i++)
+    {
+      void             *address = NSReturnAddress(i);
+
+      [frames addObject: [NSString stringWithFormat: @"%p", address]];
+    }
+#endif
+
+  return self;
+}
+
+- (NSEnumerator*) reverseEnumerator
+{
+  return [frames reverseObjectEnumerator];
+}
+
+@end
+
+// #endif /* GNUSTEP_BASE_MINOR_VERSION */
+// #endif /* GNUSTEP_BASE_MAJOR_VERSION */
index 4aac23ded836f8839415d92079a94c861cb2ff0b..fd3ac53126275b934a798ec893b0f661a6c38767 100644 (file)
@@ -466,27 +466,6 @@ static BOOL        showTextAttachmentsInline  = NO;
   [self _addRecipients: addrs toArray: allRecipients];
   [_info setObject: to forKey: @"to"];
 
-  /* CC processing if we reply-to-all: add all 'to' and 'cc'  */
-  if (_replyToAll)
-    {
-      to = [NSMutableArray new];
-
-      [addrs setArray: [_envelope to]];
-      [self _purgeRecipients: allRecipients
-           fromAddresses: addrs];
-      [self _addEMailsOfAddresses: addrs toArray: to];
-      [self _addRecipients: addrs toArray: allRecipients];
-
-      [addrs setArray: [_envelope cc]];
-      [self _purgeRecipients: allRecipients
-           fromAddresses: addrs];
-      [self _addEMailsOfAddresses: addrs toArray: to];
-    
-      [_info setObject: to forKey: @"cc"];
-
-      [to release];
-    }
-
   /* If "to" is empty, we add at least ourself as a recipient!
      This is for emails in the "Sent" folder that we reply to... */
   if (![to count])
@@ -508,6 +487,27 @@ static BOOL        showTextAttachmentsInline  = NO;
       [_info removeObjectForKey: @"cc"];
     }
 
+  /* CC processing if we reply-to-all: add all 'to' and 'cc'  */
+  if (_replyToAll)
+    {
+      to = [NSMutableArray new];
+
+      [addrs setArray: [_envelope to]];
+      [self _purgeRecipients: allRecipients
+           fromAddresses: addrs];
+      [self _addEMailsOfAddresses: addrs toArray: to];
+      [self _addRecipients: addrs toArray: allRecipients];
+
+      [addrs setArray: [_envelope cc]];
+      [self _purgeRecipients: allRecipients
+           fromAddresses: addrs];
+      [self _addEMailsOfAddresses: addrs toArray: to];
+    
+      [_info setObject: to forKey: @"cc"];
+
+      [to release];
+    }
+
   [allRecipients release];
   [addrs release];
 }
index 688d3f04358f04632137abe6248d50638fe0c37f..68bcfcd4c022cf18cbc28dbdb718401b9c4aae17 100644 (file)
   return filter;
 }
 
-#warning UIxContactsFoldersView should use these methods\
-         instead from now on...
-
 - (NSArray *) _subFoldersFromFolder: (SOGoParentFolder *) parentFolder
 {
   NSMutableArray *folders;
   NSEnumerator *subfolders;
   SOGoFolder *currentFolder;
-  NSString *folderName;
+  NSString *folderName, *folderOwner;
   NSMutableDictionary *currentDictionary;
   SoSecurityManager *securityManager;
 
+  folderOwner = [parentFolder ownerInContext: context];
   securityManager = [SoSecurityManager sharedSecurityManager];
-   
+
   folders = [NSMutableArray array];
 
   subfolders = [[parentFolder subFolders] objectEnumerator];
   while ((currentFolder = [subfolders nextObject]))
     {
       if (![securityManager validatePermission: SOGoPerm_AccessObject
-                           onObject: currentFolder inContext: context])
+                           onObject: currentFolder inContext: context]
+         && [[currentFolder ownerInContext: context]
+              isEqualToString: folderOwner])
        {
          folderName = [NSString stringWithFormat: @"/%@/%@",
                                 [parentFolder nameInContainer],
index 9605ed56edffccf820b05f36ed223329cc861136..c662072a001f551dc2abeffe405e733a809d19ef 100644 (file)
   return folders;
 }
 
-- (NSArray *) _foldersForUID: (NSString *) uid
-                     ofType: (NSString *) folderType
-{
-  NSObject *topFolder, *userFolder;
-  SOGoParentFolder *parentFolder;
-  NSMutableArray *folders;
-
-  folders = [NSMutableArray new];
-  [folders autorelease];
-
-  topFolder = [[[self clientObject] container] container];
-  userFolder = [topFolder lookupName: uid inContext: context acquire: NO];
-
-  /* FIXME: should be moved in the SOGo* classes. Maybe by having a SOGoFolderManager. */
-  if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"])
-    {
-      parentFolder = [userFolder lookupName: @"Calendar"
-                                inContext: context acquire: NO];
-      [folders
-       addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
-    }
-  if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
-    {
-      parentFolder = [userFolder lookupName: @"Contacts"
-                                inContext: context acquire: NO];
-      [folders
-       addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
-    }
-
-  return folders;
-}
-
-- (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
-{
-  NSMutableString *foldersString;
-  NSDictionary *currentFolder;
-
-  foldersString = [NSMutableString new];
-  [foldersString autorelease];
-
-  currentFolder = [folders nextObject];
-  while (currentFolder)
-    {
-      [foldersString appendFormat: @";%@:%@:%@",
-                    [currentFolder objectForKey: @"displayName"],
-                    [currentFolder objectForKey: @"name"],
-                    [currentFolder objectForKey: @"type"]];
-      currentFolder = [folders nextObject];
-    }
-
-  return foldersString;
-}
-
-- (WOResponse *) _foldersResponseForResults: (NSArray *) results
-                                  withType: (NSString *) folderType
-{
-  WOResponse *response;
-  NSString *uid, *foldersString;
-  NSMutableString *responseString;
-  NSDictionary *contact;
-  NSEnumerator *contacts;
-  NSArray *folders;
-
-  response = [context response];
-
-  if ([results count])
-    {
-      [response setStatus: 200];
-      [response setHeader: @"text/plain; charset=utf-8"
-                forKey: @"Content-Type"];
-
-      responseString = [NSMutableString new];
-      contacts = [results objectEnumerator];
-      while ((contact = [contacts nextObject]))
-       {
-         uid = [contact objectForKey: @"c_uid"];
-         folders = [self _foldersForUID: uid ofType: folderType];
-         foldersString
-           = [self _foldersStringForFolders: [folders objectEnumerator]];
-         [responseString appendFormat: @"%@:%@:%@%@\n", uid,
-                         [contact objectForKey: @"cn"],
-                         [contact objectForKey: @"c_email"],
-                         foldersString];
-       }
-      [response appendContentString: responseString];
-      [responseString release];
-    }
-  else
-    [response setStatus: 404];
-
-  return response;
-}
-
-- (id <WOActionResults>) foldersSearchAction
-{
-  NSString *contact, *folderType;
-  id <WOActionResults> result;
-  LDAPUserManager *um;
-
-  um = [LDAPUserManager sharedUserManager];
-  contact = [self queryParameterForKey: @"search"];
-  if ([contact length] > 0)
-    {
-      folderType = [self queryParameterForKey: @"type"];
-      result
-       = [self _foldersResponseForResults: [um fetchContactsMatching: contact]
-               withType: folderType];
-    }
-  else
-    result = [NSException exceptionWithHTTPStatus: 400
-                          reason: @"missing 'search' parameter"];
-
-  return result;
-}
-
 // - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
 // {
 //   SOGoFolder *upperContainer;
index 1b4d7eb3c6ca3d72b2947a0f5e83d27f5614340f..88da1673b8e5edd6fc0d24936636b55349fcc37e 100644 (file)
               pageName    = "UIxContactFoldersView";
               actionName  = "contactSearch";
            };
-           foldersSearch = {
-              protectedBy = "View";
-              pageName    = "UIxContactFoldersView";
-              actionName  = "foldersSearch";
-           };
            updateAdditionalAddressBooks = {
               protectedBy = "View";
               pageName    = "UIxContactFoldersView";
index 5b6b6364e00ca3610ac84e86f01449436e5f99dd..bb696b81a59b93e0afaad9ebe60c1fc993d25efe 100644 (file)
@@ -24,6 +24,7 @@
 #import <NGObjWeb/WOCookie.h>
 #import <NGObjWeb/WORequest.h>
 #import <NGObjWeb/WOResponse.h>
+
 #import <NGExtensions/NGBase64Coding.h>
 #import <NGExtensions/NSNull+misc.h>
 #import <NGExtensions/NSString+misc.h>
index c5f56913e65c4d972f55f696afad2897a4c85bf5..002e93d41ee6ed2898263f34a7594bb354388618 100644 (file)
@@ -27,6 +27,7 @@
 #import <Foundation/NSTimeZone.h>
 #import <Foundation/NSUserDefaults.h>
 #import <Foundation/NSValue.h>
+#import <NGObjWeb/NSException+HTTP.h>
 #import <NGObjWeb/WOCookie.h>
 #import <NGObjWeb/WORequest.h>
 #import <NGObjWeb/WOResponse.h>
@@ -36,6 +37,7 @@
 #import <Appointments/SOGoFreeBusyObject.h>
 #import <SoObjects/SOGo/SOGoWebAuthenticator.h>
 #import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/SOGoUserFolder.h>
 #import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
 #import <SOGoUI/UIxComponent.h>
 
@@ -230,4 +232,85 @@ static NSString *defaultModule = nil;
   return response;
 }
 
+- (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
+{
+  NSMutableString *foldersString;
+  NSDictionary *currentFolder;
+
+  foldersString = [NSMutableString new];
+  [foldersString autorelease];
+
+  currentFolder = [folders nextObject];
+  while (currentFolder)
+    {
+      [foldersString appendFormat: @";%@:%@:%@",
+                    [currentFolder objectForKey: @"displayName"],
+                    [currentFolder objectForKey: @"name"],
+                    [currentFolder objectForKey: @"type"]];
+      currentFolder = [folders nextObject];
+    }
+
+  return foldersString;
+}
+
+- (WOResponse *) _foldersResponseForResults: (NSDictionary *) results
+{
+  WOResponse *response;
+  NSString *uid, *foldersString;
+  NSMutableString *responseString;
+  NSDictionary *contact;
+  NSEnumerator *contacts;
+  NSArray *folders;
+
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/plain; charset=utf-8"
+           forKey: @"Content-Type"];
+
+  responseString = [NSMutableString new];
+  contacts = [[results allKeys] objectEnumerator];
+  while ((contact = [contacts nextObject]))
+    {
+      uid = [contact objectForKey: @"c_uid"];
+      folders = [results objectForKey: contact];
+      foldersString
+       = [self _foldersStringForFolders: [folders objectEnumerator]];
+      [responseString appendFormat: @"%@:%@:%@%@\n", uid,
+                     [contact objectForKey: @"cn"],
+                     [contact objectForKey: @"c_email"],
+                     foldersString];
+    }
+  [response appendContentString: responseString];
+  [responseString release];
+
+  return response;
+}
+
+- (id <WOActionResults>) foldersSearchAction
+{
+  NSString *contact, *folderType;
+  NSDictionary *folders;
+  id <WOActionResults> result;
+
+  contact = [self queryParameterForKey: @"search"];
+  if ([contact length])
+    {
+      folderType = [self queryParameterForKey: @"type"];
+      if ([folderType length])
+       {
+         folders = [[self clientObject] foldersOfType: folderType
+                                        matchingUID: contact];
+         result = [self _foldersResponseForResults: folders];
+       }
+      else
+       result = [NSException exceptionWithHTTPStatus: 400
+                             reason: @"missing 'type' parameter"];
+    }
+  else
+    result = [NSException exceptionWithHTTPStatus: 400
+                          reason: @"missing 'search' parameter"];
+
+  return result;
+}
+
 @end
index b41123a7c08be8a7de35c7d48abfd4c3dc63013a..63e2c5f8e79f0aaea45666c114cb5b1762c7673e 100644 (file)
           pageName = "SOGoUserHomePage";
          actionName = "logoff";
        };
+       foldersSearch = {
+         protectedBy = "View";
+         pageName = "SOGoUserHomePage";
+         actionName = "foldersSearch";
+       };
       };
     };
     SOGoGroupsFolder = {
index a0a3dcfe9c9721e8a6daa845d5e2a5826fc717d3..c19f0004de91dba655ed862e9de6d2e51b73c7b0 100644 (file)
@@ -663,8 +663,7 @@ DIV#rightDragHandle
     overflow: visible; }
 
   TD.mailer_fieldname
-  { text-align: left;
-    width: auto; }
+  { text-align: left; }
 
   TD.mailer_fieldvalue
   { white-space: normal; }
index 657ea7557efeb8d03ecfe3d3ad0c44a1b544fc91..894df77c578fb29764f561345109b3d6cf1aab68 100644 (file)
@@ -255,9 +255,11 @@ function deleteSelectedMessagesCallback(http) {
 //     row.addClassName("deleted"); // when we'll offer "mark as deleted"
       
        if (deleteMessageRequestCount == 0) {
-         if (nextRow)
+         if (nextRow) {
            Mailer.currentMessages[Mailer.currentMailbox] = nextRow.getAttribute("id").substr(4);
-         openMailbox(data["mailbox"], true);
+           nextRow.select();
+           loadMessage(Mailer.currentMessages[Mailer.currentMailbox]);
+         }
        }
       }
     }
@@ -522,7 +524,10 @@ function messageListCallback(http) {
       if (row) {
        row.select();
        lastClickedRow = row.rowIndex - $(row).up('table').down('thead').getElementsByTagName('tr').length;  
-       div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
+       var rowPosition = row.rowIndex * row.getHeight();
+       if ($(row).up('div').getHeight() > rowPosition)
+         rowPosition = 0;
+       div.scrollTop = rowPosition; // scroll to selected message
       }
       else
        $("messageContent").update();
@@ -715,7 +720,6 @@ function onMessageSelectionChange() {
 
   if (rows.length == 1) {
     var idx = rows[0].substr(4);
-
     if (Mailer.currentMessages[Mailer.currentMailbox] != idx) {
       Mailer.currentMessages[Mailer.currentMailbox] = idx;
       loadMessage(idx);
index da4c678d8138d947f0ee0475b744e2e8d1897cb2..e4ebdd0d192f04152911a69205d9511d3a18387e 100644 (file)
@@ -74,7 +74,8 @@ function _editEventId(id, calendar) {
   var targetname = "SOGo_edit_" + id;
   var win = window.open(urlstr, "_blank",
                         "width=490,height=470,resizable=0");
-  win.focus();
+  if (win)
+    win.focus();
 }
 
 function editEvent() {
@@ -346,8 +347,8 @@ function eventsListCallback(http) {
        startDate.setTime(data[i][4] * 1000);
        row.day = startDate.getDayString();
        row.hour = startDate.getHourString();
-       Event.observe(row, "click",
-                     onEventClick.bindAsEventListener(row));
+       Event.observe(row, "mousedown", onRowClick);
+       Event.observe(row, "selectstart", listRowMouseDownHandler);
        Event.observe(row, "dblclick",
                      editDoubleClickedEvent.bindAsEventListener(row));
        Event.observe(row, "contextmenu",
@@ -391,7 +392,6 @@ function tasksListCallback(http) {
       var data = http.responseText.evalJSON(true);
 
       for (var i = 0; i < data.length; i++) {
-       //log(i + " = " + data[i][3]);
        var listItem = document.createElement("li");
        list.appendChild(listItem);
        Event.observe(listItem, "mousedown", listRowMouseDownHandler);
@@ -400,6 +400,7 @@ function tasksListCallback(http) {
                      editDoubleClickedEvent.bindAsEventListener(listItem));
        listItem.setAttribute("id", data[i][0]);
        $(listItem).addClassName(data[i][5]);
+       $(listItem).addClassName(data[i][6]);
        listItem.calendar = data[i][1];
        $(listItem).addClassName("calendarFolder" + data[i][1]);
        listItem.cname = escape(data[i][0]);
@@ -919,21 +920,10 @@ function popupCalendar(node) {
 
 function onEventContextMenu(event) {
   var topNode = $("eventsList");
-//   log(topNode);
-
   var menu = $("eventsListMenu");
 
   Event.observe(menu, "hideMenu",  onEventContextMenuHide);
   popupMenu(event, "eventsListMenu", this);
-
-  var topNode = $("eventsList");
-  var selectedNodes = topNode.getSelectedRows();
-  topNode.menuSelectedRows = selectedNodes;
-  for (var i = 0; i < selectedNodes.length; i++)
-    selectedNodes[i].deselect();
-
-  topNode.menuSelectedEntry = this;
-  this.select();
 }
 
 function onEventContextMenuHide(event) {
@@ -943,20 +933,20 @@ function onEventContextMenuHide(event) {
     topNode.menuSelectedEntry.deselect();
     topNode.menuSelectedEntry = null;
   }
-  if (topNode.menuSelectedRows) {
-    var nodeIds = topNode.menuSelectedRows;
-    for (var i = 0; i < nodeIds.length; i++) {
-      var node = $(nodeIds[i]);
-      node.select();
-    }
-    topNode.menuSelectedRows = null;
-  }
 }
 
 function onEventsSelectionChange() {
   listOfSelection = this;
   this.removeClassName("_unfocused");
   $("tasksList").addClassName("_unfocused");
+
+  var rows = this.tBodies[0].getSelectedNodes();
+  if (rows.length == 1) {
+    var row = rows[0];
+    changeCalendarDisplay( { "day": row.day,
+         "scrollEvent": row.getAttribute("id") } );
+    changeDateSelectorDisplay(row.day);
+  }
 }
 
 function onTasksSelectionChange() {
@@ -1048,14 +1038,6 @@ function onListFilterChange() {
   return refreshEvents();
 }
 
-function onEventClick(event) {
-  changeCalendarDisplay( { "day": this.day,
-       "scrollEvent": this.getAttribute("id") } );
-  changeDateSelectorDisplay(this.day);
-  
-  return onRowClick(event);
-}
-
 function selectMonthInMenu(menu, month) {
    var entries = menu.childNodes[1].childNodesWithTag("LI");
    for (i = 0; i < entries.length; i++) {
@@ -1721,9 +1703,6 @@ function configureLists() {
    TableKit.Resizable.init(list, {'trueResize' : true, 'keepWidth' : true});
    Event.observe(list, "mousedown",
                 onEventsSelectionChange.bindAsEventListener(list));
-   var div = list.parentNode;
-   Event.observe(div, "contextmenu",
-                onEventContextMenu.bindAsEventListener(div));
 }
 
 function initDateSelectorEvents() {
index 1855cc45e0594c2e06b130270f573b7b6353731b..fe55efc34c929ae4018f6a5e24eaeb7370f88d4d 100644 (file)
@@ -1,8 +1,8 @@
 function onSearchFormSubmit() {
   var searchValue = $("searchValue");
 
-  var url = (ApplicationBaseURL
-            + "/foldersSearch?ldap-only=YES&search=" + escape(searchValue.value)
+  var url = (UserFolderURL
+            + "foldersSearch?search=" + escape(searchValue.value)
             + "&type=" + window.opener.userFolderType);
   if (document.userFoldersRequest) {
      document.userFoldersRequest.aborted = true;
@@ -30,7 +30,7 @@ function addLineToTree(tree, parent, line) {
       for (var i = 1; i < nodes.length; i++) {
         var folderInfos = nodes[i].split(":");
         var icon = ResourcesURL + '/';
-        if (folderInfos[2] == 'Contacts')
+        if (folderInfos[2] == 'Contact')
            icon += 'tb-mail-addressbook-flat-16x16.png';
         else
            icon += 'calendar-folder-16x16.png';
@@ -97,6 +97,7 @@ function userFoldersCallback(http) {
       if (http.status == 200) {
         var response = http.responseText;
         div.innerHTML = buildTree(http.responseText);
+        div.clean = false;
         var nodes = document.getElementsByClassName("node", $("d"));
         for (i = 0; i < nodes.length; i++)
           Event.observe(nodes[i], "click", onFolderTreeItemClick.bindAsEventListener(nodes[i]));
@@ -136,9 +137,17 @@ function onConfirmFolderSelection(event) {
    }
 }
 
+function onFolderSearchKeyDown(event) {
+  var div = $("folders");
+  if (!div.clean) {
+    div.innerHTML = "";
+    div.clean = true;
+  }
+}
+
 function initUserFoldersWindow() {
-   configureSearchField();
-   Event.observe($("addButton"), "click",  onConfirmFolderSelection);
+  $("searchValue").observe("keydown", onFolderSearchKeyDown);
+  $("addButton").observe("click",  onConfirmFolderSelection);
 }
 
 FastInit.addOnLoad(initUserFoldersWindow);
index 4a30bdf51478df9359cb247dd024d58f92ffb9bc..e76dfd54cafc4a6607b4b5453f205b298f769c7b 100644 (file)
@@ -140,20 +140,20 @@ function addressFieldLostFocus(sender) {
 }
 
 function removeLastEditedRowIfEmpty() {
-  var idx, addr, addressList, senderRow;
+  var addr, addressList, senderRow;
   
-  idx = lastIndex;
-  if (idx == 0) return;
-  addr = $('addr_' + idx);
+  addressList = $("addressList").tBodies[0];
+  
+  if (lastIndex == 0 && addressList.childNodes.length <= 2) return;
+  addr = $('addr_' + lastIndex);
   if (!addr) return;
   if (addr.value.strip() != '') return;
-  addr = this.findAddressWithIndex(idx);
+  addr = this.findAddressWithIndex(lastIndex);
   if(addr) {
     var addresses = $('addr_addresses');
     addresses.removeChild(addr);
   }
-  addressList = $("addressList").tBodies[0];
-  senderRow = $("row_" + idx);
+  senderRow = $("row_" + lastIndex);
   addressList.removeChild(senderRow);
 }
 
index ce1bace1bb87a762e93cf3d805451994461ccd54..6313cd2ea74df4103e7a2394337ac36686bcd356 100644 (file)
@@ -509,9 +509,10 @@ function onRowClick(event) {
   }
 
   var initialSelection = $(node.parentNode).getSelectedNodes();
-
-  if (initialSelection.length > 0 && !Event.isLeftClick(event))
-    // Ignore non primary-click (ie right-click)
+  if (initialSelection.length > 0 
+      && initialSelection.indexOf(node) >= 0
+      && !Event.isLeftClick(event))
+    // Ignore non primary-click (ie right-click) inside current selection
     return true;
   
   if ((event.shiftKey == 1 || event.ctrlKey == 1)
@@ -917,7 +918,12 @@ function onSearchKeyDown(event) {
   if (this.timer)
     clearTimeout(this.timer);
 
-  this.timer = setTimeout("onSearchFormSubmit()", 1000);
+  if (event.keyCode == 13) {
+    onSearchFormSubmit();
+    event.preventDefault();
+  }
+  else
+    this.timer = setTimeout("onSearchFormSubmit()", 1000);
 }
 
 function onSearchFormSubmit(event) {