]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1174 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sat, 15 Sep 2007 01:56:19 +0000 (01:56 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sat, 15 Sep 2007 01:56:19 +0000 (01:56 +0000)
41 files changed:
ChangeLog
NEWS
SoObjects/Appointments/SOGoAppointmentFolder.h
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Appointments/SOGoAppointmentFolders.h [new file with mode: 0644]
SoObjects/Appointments/SOGoAppointmentFolders.m [new file with mode: 0644]
SoObjects/Appointments/SOGoFreeBusyObject.m
SoObjects/Appointments/SOGoTaskObject.m
SoObjects/SOGo/SOGoFolder.h
SoObjects/SOGo/SOGoFolder.m
UI/Common/English.lproj/Localizable.strings
UI/Common/French.lproj/Localizable.strings
UI/Common/German.lproj/Localizable.strings
UI/Common/UIxFolderActions.m
UI/Common/UIxParentFolderActions.h [new file with mode: 0644]
UI/Common/UIxParentFolderActions.m [new file with mode: 0644]
UI/Common/UIxToolbar.m
UI/Common/product.plist
UI/Contacts/English.lproj/Localizable.strings
UI/Contacts/French.lproj/Localizable.strings
UI/Contacts/German.lproj/Localizable.strings
UI/MailerUI/English.lproj/Localizable.strings
UI/MailerUI/French.lproj/Localizable.strings
UI/Scheduler/English.lproj/Localizable.strings
UI/Scheduler/French.lproj/Localizable.strings
UI/Scheduler/German.lproj/Localizable.strings
UI/Scheduler/UIxCalMainView.m
UI/Scheduler/UIxCalendarSelector.m
UI/Scheduler/product.plist
UI/Templates/SchedulerUI/UIxComponentEditor.wox
UI/Templates/UIxPageFrame.wox
UI/Templates/UIxToolbar.wox
UI/WebServerResources/ContactsUI.css
UI/WebServerResources/ContactsUI.js
UI/WebServerResources/HTMLTableElement.js
UI/WebServerResources/MailerUI.css
UI/WebServerResources/MailerUI.js
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxComponentEditor.js
UI/WebServerResources/generic.css
UI/WebServerResources/generic.js

index 8ce905a88f479a5ceebcb1aafd9e71c3bcf54d27..a4c799c2f9a123cc68889f961fa9e7f8bec37e1e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2007-09-14  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([-deleteEntriesWithIds:ids]): moved method into SOGoFolder.
+
+       * UI/Scheduler/UIxCalMainView.m ([-batchDeleteAction]): moved
+       method into UIxFolderActions.
+
+       * SoObjects/Appointments/SOGoFreeBusyObject.m ([SOGoFreeBusyObject
+       -fetchFreeBusyInfosFrom:_startDateto:_endDate]): fetch the
+       freebusy info from the "personal" calendar.
+
+       * UI/Common/UIxParentFolderActions.m ([UIxParentFolderActions
+       -createFolderAction]): new standardized method for requesting
+       folder creations among gcs-based modules.
+
+       * UI/Common/UIxParentFolderActions.[hm]: new action class module.
+
+       * SoObjects/Appointments/SOGoAppointmentFolders.m: new class
+       module, equivalent to the SOGoParentFolder's child
+       SOGoContactFolders, but for calendars.
+
        * SoObjects/SOGo/SOGoObject.m ([SOGoObject -labelForKey:key]): new
        method that returns translated strings for controller bundles
        (same as what UIxComponent does for view bundles).
diff --git a/NEWS b/NEWS
index b51426397a7cced75661179fc919fbb070857d11..e6fe36e0f69ac024a81b2cdc8e2c56457bc09075 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,11 @@
   given during an indirect bind;
 - deleting a message no longer expunges its parent folder;
 - implemented support for multiple calendars;
-- it is not possible to rename folders;
+- it is now possible to rename folders;
 - fixed search in message content;
+- added tooltips for toolbar buttons (English and French);
+- added checkmarks in live search options popup menus;
+- initial support for resizable columns in tables;
 - countless bugfixes;
 
 0.9.0-20070824
index 06edea0e6e4aac7aea9528b5fe8bc7a13439982c..5f5ee41d6abcc409cd7209274fb0f234ab7d7474 100644 (file)
@@ -84,8 +84,6 @@
 - (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
                                   to: (NSCalendarDate *) _endDate;
 
-- (void) deleteEntriesWithIds: (NSArray *) ids;
-
 /* URL generation */
 
 - (NSString *) baseURLForAptWithUID: (NSString *) _uid
index 38c34a943cc9347f09765530538ed2a99cfd81d0..a517d18df56ec7ce56fdd57505cf653ddf481cf4 100644 (file)
@@ -933,26 +933,6 @@ static NSNumber   *sharedYes = nil;
                component: _component];
 }
 
-- (void) deleteEntriesWithIds: (NSArray *) ids
-{
-  Class objectClass;
-  unsigned int count, max;
-  NSString *currentId;
-  id deleteObject;
-
-  max = [ids count];
-  for (count = 0; count < max; count++)
-    {
-      currentId = [ids objectAtIndex: count];
-      objectClass
-        = [self objectClassForResourceNamed: currentId];
-      deleteObject = [objectClass objectWithName: currentId
-                                  inContainer: self];
-      [deleteObject delete];
-      [deleteObject primaryDelete];
-    }
-}
-
 /* URL generation */
 
 - (NSString *) baseURLForAptWithUID: (NSString *)_uid
diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.h b/SoObjects/Appointments/SOGoAppointmentFolders.h
new file mode 100644 (file)
index 0000000..287a090
--- /dev/null
@@ -0,0 +1,32 @@
+/* SOGoAppointmentFolders.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 SOGOAPPOINTMENTFOLDERS_H
+#define SOGOAPPOINTMENTFOLDERS_H
+
+#import <SoObjects/SOGo/SOGoParentFolder.h>
+
+@interface SOGoAppointmentFolders : SOGoParentFolder
+
+@end
+
+#endif /* SOGOAPPOINTMENTFOLDERS_H */
diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.m b/SoObjects/Appointments/SOGoAppointmentFolders.m
new file mode 100644 (file)
index 0000000..151f66f
--- /dev/null
@@ -0,0 +1,46 @@
+/* SOGoAppointmentFolders.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/NSString.h>
+
+#import "SOGoAppointmentFolder.h"
+
+#import "SOGoAppointmentFolders.h"
+
+@implementation SOGoAppointmentFolders
+
++ (NSString *) gcsFolderType
+{
+  return @"Appointment";
+}
+
++ (Class) subFolderClass
+{
+  return [SOGoAppointmentFolder class];
+}
+
+- (NSString *) defaultFolderName
+{
+  return @"Personal calendar";
+}
+
+@end
index bddee8ace64bc7575e1677ed7bac6e017f124932..ef40274dcc4d888d49d86ba37ba8d7b59455d05b 100644 (file)
@@ -35,6 +35,8 @@
 #import <SOGo/SOGoUser.h>
 #import <SOGo/SOGoPermissions.h>
 
+#import "SOGoAppointmentFolder.h"
+
 #import "SOGoFreeBusyObject.h"
 
 @interface SOGoFreeBusyObject (PrivateAPI)
 - (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
                                   to: (NSCalendarDate *) _endDate
 {
-  id calFolder;
+  SOGoAppointmentFolder *calFolder;
 //   SoSecurityManager *sm;
   NSArray *infos;
 
-  calFolder = [container lookupName: @"Calendar" inContext: nil acquire: NO];
+  calFolder = [[container lookupName: @"Calendar" inContext: nil acquire: NO]
+               lookupName: @"personal" inContext: nil acquire: NO];
 //   sm = [SoSecurityManager sharedSecurityManager];
 //   if (![sm validatePermission: SOGoPerm_FreeBusyLookup
 //            onObject: calFolder
 //            inContext: context])
-    infos = [calFolder fetchFreeBusyInfosFrom: _startDate
-                       to: _endDate];
+  infos = [calFolder fetchFreeBusyInfosFrom: _startDate
+                    to: _endDate];
 //   else
 //     {
 //       infos = [NSArray new];
index 2357ac8b2ef6bde8ebce1ca3efd8a4f699fd440c..5c628fa6635616c4833afab4c105132579927134 100644 (file)
@@ -160,38 +160,38 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   }
   return allErrors;
 }
-- (NSException *)deleteInUIDs:(NSArray *)_uids {
-  NSEnumerator *e;
-  id           folder;
-  NSException  *allErrors = nil;
+// - (NSException *)deleteInUIDs:(NSArray *)_uids {
+//   NSEnumerator *e;
+//   id           folder;
+//   NSException  *allErrors = nil;
   
-  e = [[container lookupCalendarFoldersForUIDs: _uids inContext: context]
-            objectEnumerator];
-  while ((folder = [e nextObject])) {
-    NSException           *error;
-    SOGoTaskObject *task;
+//   e = [[container lookupCalendarFoldersForUIDs: _uids inContext: context]
+//          objectEnumerator];
+//   while ((folder = [e nextObject])) {
+//     NSException           *error;
+//     SOGoTaskObject *task;
     
-    task = [folder lookupName: [self nameInContainer]
-                  inContext: context
-                   acquire: NO];
-    if (![task isNotNull]) {
-      [self logWithFormat:@"Note: did not find '%@' in folder: %@",
-             [self nameInContainer], folder];
-      continue;
-    }
-    if ([task isKindOfClass: [NSException class]]) {
-      [self logWithFormat:@"Exception: %@", [(NSException *) task reason]];
-      continue;
-    }
+//     task = [folder lookupName: [self nameInContainer]
+//                inContext: context
+//                    acquire: NO];
+//     if (![task isNotNull]) {
+//       [self logWithFormat:@"Note: did not find '%@' in folder: %@",
+//           [self nameInContainer], folder];
+//       continue;
+//     }
+//     if ([task isKindOfClass: [NSException class]]) {
+//       [self logWithFormat:@"Exception: %@", [(NSException *) task reason]];
+//       continue;
+//     }
     
-    if ((error = [task primaryDelete]) != nil) {
-      [self logWithFormat:@"Note: failed to delete in folder: %@", folder];
-      // TODO: make compound
-      allErrors = error;
-    }
-  }
-  return allErrors;
-}
+//     if ((error = [task primaryDelete]) != nil) {
+//       [self logWithFormat:@"Note: failed to delete in folder: %@", folder];
+//       // TODO: make compound
+//       allErrors = error;
+//     }
+//   }
+//   return allErrors;
+// }
 
 /* "iCal multifolder saves" */
 
@@ -396,45 +396,48 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
      - delete in removed folders
      - send iMIP mail for all folders not found
   */
-  iCalToDo *task;
-  NSArray         *removedUIDs;
-  NSMutableArray  *attendees;
+//   iCalToDo *task;
+//   NSArray         *removedUIDs;
+//   NSMutableArray  *attendees;
 
-  /* load existing content */
+  [self primaryDelete];
+
+  return nil;
+//   /* load existing content */
   
-  task = (iCalToDo *) [self component: NO];
+//   task = (iCalToDo *) [self component: NO];
   
-  /* compare sequence if requested */
+//   /* compare sequence if requested */
 
-  if (_v != 0) {
-    // TODO
-  }
+//   if (_v != 0) {
+//     // TODO
+//   }
   
-  removedUIDs = [self attendeeUIDsFromTask:task];
+//   removedUIDs = [self attendeeUIDsFromTask:task];
 
-  if ([self sendEMailNotifications])
-    {
-      /* send notification email to attendees excluding organizer */
-      attendees = [NSMutableArray arrayWithArray:[task attendees]];
-      [attendees removePerson:[task organizer]];
+//   if ([self sendEMailNotifications])
+//     {
+//       /* send notification email to attendees excluding organizer */
+//       attendees = [NSMutableArray arrayWithArray:[task attendees]];
+//       [attendees removePerson:[task organizer]];
   
-      /* flag task as being cancelled */
-      [(iCalCalendar *) [task parent] setMethod: @"cancel"];
-      [task increaseSequence];
-
-      /* remove all attendees to signal complete removal */
-      [task removeAllAttendees];
-
-      /* send notification email */
-      [self sendEMailUsingTemplateNamed: @"Deletion"
-            forOldObject: nil
-            andNewObject: task
-            toAttendees: attendees];
-    }
+//       /* flag task as being cancelled */
+//       [(iCalCalendar *) [task parent] setMethod: @"cancel"];
+//       [task increaseSequence];
+
+//       /* remove all attendees to signal complete removal */
+//       [task removeAllAttendees];
+
+//       /* send notification email */
+//       [self sendEMailUsingTemplateNamed: @"Deletion"
+//             forOldObject: nil
+//             andNewObject: task
+//             toAttendees: attendees];
+//     }
 
-  /* perform */
+//   /* perform */
   
-  return [self deleteInUIDs:removedUIDs];
+//   return [self deleteInUIDs:removedUIDs];
 }
 
 - (NSException *)saveContentString:(NSString *)_iCalString {
index ed57b8059530bceac1873d63e8680a5e2d2a7edc..ccca8e7d7f095bf9174cd2db2adb0e81a81f7c03 100644 (file)
@@ -66,6 +66,8 @@
 /* lower level fetches */
 - (BOOL) nameExistsInFolder: (NSString *) objectName;
 
+- (void) deleteEntriesWithIds: (NSArray *) ids;
+
 - (NSArray *) fetchContentObjectNames;
 - (NSDictionary *) fetchContentStringsAndNamesOfAllObjects;
 
index a78d50740a1215711cac3a14350ab43c8ed83784..e0845f826cb9d546f09745bdaf30fac44d7b6427 100644 (file)
@@ -45,6 +45,7 @@
 #import "NSArray+Utilities.h"
 #import "NSString+Utilities.h"
 
+#import "SOGoContentObject.h"
 #import "SOGoPermissions.h"
 #import "SOGoUser.h"
 
@@ -338,6 +339,22 @@ static NSString *defaultUserID = @"<default>";
           && [records count] > 0);
 }
 
+- (void) deleteEntriesWithIds: (NSArray *) ids
+{
+  unsigned int count, max;
+  NSString *currentID;
+  SOGoContentObject *deleteObject;
+
+  max = [ids count];
+  for (count = 0; count < max; count++)
+    {
+      currentID = [ids objectAtIndex: count];
+      deleteObject = [self lookupName: currentID
+                          inContext: context acquire: NO];
+      [deleteObject delete];
+    }
+}
+
 - (NSDictionary *) fetchContentStringsAndNamesOfAllObjects
 {
   NSDictionary *files;
index 9f20244c806197fb201768380c329e3edc2aa29b..f25d4d2f4b639f46cd33e0f689d4713105bf7ef2 100644 (file)
 "Sorry, the user rights can not be configured for that object." = "Sorry, the user rights can not be configured for that object.";
 
 /* generic.js */
-"Unable to subscribe to that folder!" = "Unable to subscribe to that folder!";
-"You cannot subscribe to a folder that you own!" = "You cannot subscribe to a folder that you own!";
-"Unable to unsubscribe from that folder!" = "Unable to unsubscribe from that folder!";
-"You cannot unsubscribe from a folder that you own!" = "You cannot unsubscribe from a folder that you own!";
+"Unable to subscribe to that folder!"
+       = "Unable to subscribe to that folder!";
+"You cannot subscribe to a folder that you own!"
+       = "You cannot subscribe to a folder that you own!";
+"Unable to unsubscribe from that folder!"
+       = "Unable to unsubscribe from that folder!";
+"You cannot unsubscribe from a folder that you own!"
+       = "You cannot unsubscribe from a folder that you own!";
 "Unable to rename that folder!" = "Unable to rename that folder!";
+"You have already subscribed to that folder!"
+       = "You have already subscribed to that folder!";
index e77de6d771dcbf6599ae4b299ab5ed286e397776..839c0bb88fa3ae5e108229fce6a0a4fa4e25ddb7 100644 (file)
@@ -34,3 +34,5 @@
 "Unable to unsubscribe from that folder!" = "Impossible de se désabonner de ce dossier.";
 "You cannot unsubscribe from a folder that you own!" = "Impossible de vous désabonner d'un dossier qui vous appartient.";
 "Unable to rename that folder!" = "Impossible de renommer ce dossier.";
+"You have already subscribed to that folder!"
+       = "Vous Ãªtes déja abonné Ã  ce dossier.";
index 9a0bb6969c2fd664b7a1fa7bbb98e779d787cfae..a7feaba384c35be2c6933133958b959bc6c7f706 100644 (file)
@@ -36,3 +36,5 @@
 "Unable to unsubscribe from that folder!" = "Unmöglich sich von diesem Ordner zu des-abonnieren.";
 "You cannot unsubscribe from a folder that you own!" = "Unmöglich sich von einem Ordner zu des-abonnieren, der Ihnen selbst gehört.";
 "Unable to rename that folder!" = "Unable to rename that folder!";
+"You have already subscribed to that folder!"
+       = "You have already subscribed to that folder!";
index e152ed3357d6d13a09d7d0f8d2a7813e7a079280..943fbafe4f8aa31c66ff6e6c32b72d40e56a8449 100644 (file)
@@ -49,7 +49,8 @@
 
 - (void) _setupContext
 {
-  NSString *clientClass, *mailInvitationParam;
+  NSString *folder, *mailInvitationParam;
+  NSArray *realFolderPath;
   SOGoUser *activeUser;
 
   activeUser = [context activeUser];
   clientObject = [self clientObject];
   owner = [clientObject ownerInContext: nil];
 
-  clientClass = NSStringFromClass([clientObject class]);
-  if ([clientClass isEqualToString: @"SOGoContactGCSFolder"])
-    baseFolder = @"Contacts";
-  else if ([clientClass isEqualToString: @"SOGoAppointmentFolder"])
-    baseFolder = @"Calendar";
-  else
-    baseFolder = nil;
+  baseFolder = [[clientObject container] nameInContainer];
 
   um = [LDAPUserManager sharedUserManager];
   ud = [activeUser userSettings];
     }
   [ud setObject: moduleSettings forKey: baseFolder];
 
+  realFolderPath = [[clientObject nameInContainer]
+                    componentsSeparatedByString: @"_"];
+  if ([realFolderPath count] > 1)
+    folder = [realFolderPath objectAtIndex: 1];
+  else
+    folder = [realFolderPath objectAtIndex: 0];
   subscriptionPointer = [NSString stringWithFormat: @"%@:%@/%@",
-                                 owner, baseFolder,
-                                 [clientObject nameInContainer]];
+                                 owner, baseFolder, folder];
 
   mailInvitationParam
     = [[context request] formValueForKey: @"mail-invitation"];
   return response;
 }
 
+- (id) batchDeleteAction
+{
+  WOResponse *response;
+  NSString *idsParam;
+  NSArray *ids;
+
+  idsParam = [[context request] formValueForKey: @"ids"];
+  ids = [idsParam componentsSeparatedByString: @"/"];
+  if ([ids count])
+    {
+      clientObject = [self clientObject];
+      [clientObject deleteEntriesWithIds: ids];
+      response = [self responseWith204];
+    }
+  else
+    {
+      response = [self responseWithStatus: 500];
+      [response appendContentString: @"At least 1 id required."];
+    }
+  
+  return response;
+}
+
 @end
diff --git a/UI/Common/UIxParentFolderActions.h b/UI/Common/UIxParentFolderActions.h
new file mode 100644 (file)
index 0000000..c380f06
--- /dev/null
@@ -0,0 +1,31 @@
+/* UIxParentFolderActions.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 UIXPARENTFOLDERACTIONS_H
+#define UIXPARENTFOLDERACTIONS_H
+
+#import <NGObjWeb/WODirectAction.h>
+
+@interface UIxParentFolderActions : WODirectAction
+@end
+
+#endif /* UIXPARENTFOLDERACTIONS_H */
diff --git a/UI/Common/UIxParentFolderActions.m b/UI/Common/UIxParentFolderActions.m
new file mode 100644 (file)
index 0000000..8f75993
--- /dev/null
@@ -0,0 +1,61 @@
+/* UIxParentFolderActions.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/NSString.h>
+
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/WORequest.h>
+
+#import <UI/Common/WODirectAction+SOGo.h>
+#import <SoObjects/SOGo/SOGoParentFolder.h>
+
+#import "UIxParentFolderActions.h"
+
+@implementation UIxParentFolderActions
+
+- (id <WOActionResults>) createFolderAction
+{
+  WOResponse *response;
+  NSString *name, *nameInContainer;
+
+  name = [[context request] formValueForKey: @"name"];
+  if ([name length] > 0)
+    {
+      response = (WOResponse *) [[self clientObject] newFolderWithName: name
+                                                    nameInContainer: &nameInContainer];
+      if (!response)
+       {
+         response = [self responseWithStatus: 201];
+         [response setHeader: @"text/plain; charset=us-ascii"
+                   forKey: @"content-type"];
+         [response appendContentString: nameInContainer];
+       }
+    }
+  else
+    response = [NSException exceptionWithHTTPStatus: 400
+                            reason: @"The name is missing"];
+  
+  return response;
+}
+
+@end
index e7fd1009757ff64e50de237cf67cee3e1af468c2..1959aaac6da3a34b11520a4faaf1aa50a0cc43b3 100644 (file)
   return image;
 }
 
+- (NSString *) buttonTooltip
+{
+  NSString          *key;
+  
+  key = [[self buttonInfo] valueForKey: @"tooltip"];
+
+  return [self labelForKey: key];
+}
+
 /* enable/disable buttons */
 
 - (BOOL)isButtonEnabled {
index 704880c100703579b3fc339abec1d5750aa7f19e..b9b6d7e7e1c1d6c94b09316f71cb7b4e584a7539 100644 (file)
          actionClass = "UIxFolderActions";
          actionName  = "renameFolder";
        };
+       batchDelete = {
+         protectedBy = "Delete Objects";
+         actionClass = "UIxFolderActions";
+         actionName  = "batchDelete";
+       };
       };
     };
   };
index f7d9db02879caa2bac5e53a24dc9d1fa37006ff3..08044be83fdcb247817977ae3db01e08171c2b8a 100644 (file)
 "invalidemailwarn" = "invalidemailwarn";
 "new" = "new";
 
+/* Tooltips */
+
+"Create a new address book card" = "Create a new address book card";
+"Create a new list" = "Create a new list";
+"Edit the selected card" = "Edit the selected card";
+"Send a mail message" = "Send a mail message";
+"Delete selected card or address book" = "Delete selected card or address book";
+
 "htmlMailFormat_UNKNOWN" = "Unknown";
 "htmlMailFormat_FALSE" = "Plain Text";
 "htmlMailFormat_TRUE" = "HTML";
 = "This person can read the cards of this addressbook.";
 "This person can erase cards from this addressbook."
 = "This person can erase cards from this addressbook.";
+
+"The selected contact has no email address."
+= "The selected contact has no email address.";
index 7574940685ca881290a2c47fe328b6d34747b0e4..5bf201634767757e710a4e7b6b3c45c51d476370 100644 (file)
 "invalidemailwarn"  = "Champ de l'email invalide, continuer quand même ?";
 "new"               = "Nouveau";
 
+/* Tooltips */
+
+"Create a new address book card" = "Créer une nouvelle fiche";
+"Create a new list" = "Créer une nouvelle liste de diffusion";
+"Edit the selected card" = "Modifier la fiche sélectionnée";
+"Send a mail message" = "Rédiger un courrier Ã  la sélection";
+"Delete selected card or address book" = "Supprimer la fiche sélectionnée";
+
 "htmlMailFormat_UNKNOWN" = "Inconnu";
 "htmlMailFormat_FALSE" = "Texte simple (sans HTML)";
 "htmlMailFormat_TRUE" = "HTML";
 "This person can erase cards from this addressbook."
 = "Cette personne peut effacer des fiches de ce carnet d'adresses.";
 
+"The selected contact has no email address."
+= "Cette personne n'a pas d'adresse courriel.";
+
index 19bd4387e7a89bed5c6723fd28ef845159ed133d..6d27d4e40af4e29dc2962af10359c14b5002b3e2 100644 (file)
 = "Diese Person kann Karten dieses Adressbuches anzeigen.";
 "This person can erase cards from this addressbook."
 = "Diese Person kann Karten aus diesem Adressbuch löschen";
+
+"The selected contact has no email address."
+= "The selected contact has no email address.";
index 9e18ecd3037b8ced6aaee34c91bdf269fbc9d086..b058b07a19fe528df61042af8e45203c63068bc7 100644 (file)
 "Attach" = "Attach";
 "Save" = "Save";
 
+/* Tooltips */
+
+"Send this message now" = "Send this message now";
+"Select a recipient from an Address Book" = "Select a recipient from an Address Book";
+"Include an attachment" = "Include an attachment";
+"Save this message" = "Save this message";
+"Get new messages" = "Get new messages";
+"Create a new message" = "Create a new message";
+"Go to address book" = "Go to address book";
+"Reply to the message" = "Reply to the message";
+"Reply to sender and all recipients" = "Reply to sender and all recipients";
+"Forward selected message" = "Forward selected message";
+"Delete selected message or folder" = "Delete selected message or folder";
+"Mark the selected messages as junk" = "Mark the selected messages as junk";
+"Print this message" = "Print this message";
+"Stop the current transfer" = "Stop the current transfer";
+
 /* Main Frame  */
 
 "Home"                 = "Home"; 
index 20f782224a9848013a254b944b40ce28d7a69aed..cf34cac37e4cdad0ad5ae5a7aabbd27b4248f0bd 100644 (file)
 "Attach" = "Joindre";
 "Save" = "Enregistrer";
 
+/* Tooltips */
+
+"Send this message now" = "Envoyer le message maintenant";
+"Select a recipient from an Address Book" = "Sélectionner un destinataire du carnet d'adresses";
+"Include an attachment" = "Inclure une pièce jointe";
+"Save this message" = "Enregistrer ce message";
+"Get new messages" = "Relever les nouveaux messages";
+"Create a new message" = "Créer un nouveau message";
+"Go to address book" = "Ouvrir le carnet d'adresses";
+"Reply to the message" = "Répondre au message";
+"Reply to sender and all recipients" = "Répondre Ã  l'expéditeur et Ã  tous les destinataires";
+"Forward selected message" = "Transférer le message sélectionné";
+"Delete selected message or folder" = "Supprimer le message ou le dossier sélectionné";
+"Mark the selected messages as junk" = "Marquer les messages sélectionnés comme indésirables";
+"Print this message" = "Imprimer ce message";
+"Stop the current transfer" = "Arrêter le transfert courant";
+
 /* Main Frame  */
 
 "Home"                 = "Accueil"; 
index 5e7ee587b641171819ab46016c52241e05fa8f20..fde04128b507dfc6aa0aee09dd35b6dcadc4bbbe 100644 (file)
@@ -1,5 +1,16 @@
 /* this file is in UTF-8 format! */
 
+/* Tooltips */
+
+"Create a new event" = "Create a new event";
+"Create a new task" = "Create a new task";
+"Edit this event or task" = "Edit this event or task";
+"Delete this event or task" = "Delete this event or task";
+"Go to today" = "Go to today";
+"Switch to day view" = "Switch to day view";
+"Switch to week view" = "Switch to week view";
+"Switch to month view" = "Switch to month view";
+
 /* Day */
 
 "Sunday" = "Sunday";
@@ -368,6 +379,9 @@ validate_endbeforestart    = "Enddate is before startdate!";
 "eventDeleteConfirmation" = "Erasing this event will be permanent.\\nWould you like to continue?";
 "taskDeleteConfirmation" = "Erasing this task will be permanent.\\nWould you like to continue?";
 
+"Are you sure you want to delete the selected calendar?"
+= "Are you sure you want to delete the selected calendar?";
+
 /* Legend */
 "Required participant" = "Required participant";
 "Optional participant" = "Optional participant";
index 1d8f083eb9c28748701d4a93191df5cc4386c478..ce11072569150013e7ed42262ca58b6133b1e27a 100644 (file)
@@ -1,5 +1,16 @@
 /* this file is in UTF-8 format! */
 
+/* Tooltips */
+
+"Create a new event" = "Créer un nouvel Ã©vénement";
+"Create a new task" = "Créer une nouvelle tâche";
+"Edit this event or task" = "Modifier l'événement ou la tâche sélectionnée";
+"Delete this event or task" = "Supprimer l'événement ou la tâche sélectionnée";
+"Go to today" = "Aller Ã  la journée d'aujourd'hui";
+"Switch to day view" = "Passer Ã  la vue par jour";
+"Switch to week view" = "Passer Ã  la vue par semaine";
+"Switch to month view" = "Passer Ã  la vue par mois";
+
 /* Day */
 
 "Sunday" = "Dimanche";
@@ -366,6 +377,9 @@ validate_endbeforestart    = "La date de fin est avant la date de début !";
 "eventDeleteConfirmation" = "L'effacement de cet Ã©vénement sera permanent.\\nVoulez-vous continuer?";
 "taskDeleteConfirmation" = "L'effacement de cette tâche sera permanent.\\nVoulez-vous continuer?";
 
+"Are you sure you want to delete the selected calendar?"
+= "Voulez-vous vraiment supprimer l'agenda sélectionné ?";
+
 /* Legend */
 "Required participant" = "Participant obligatoire";
 "Optional participant" = "Participant facultatif";
index b05adbc75f714cdedbcbce38f09197a903c10588..2093ad21d6c313674c58a8a0e40c23a1f300cffa 100644 (file)
@@ -366,6 +366,9 @@ validate_endbeforestart    = "Ihr Beginn ist nach dem Ende";
 "eventDeleteConfirmation" = "L'effacement de cet Ã©vénement sera permanent.\\nVoulez-vous continuer?";
 "taskDeleteConfirmation" = "L'effacement de cette tâche sera permanent.\\nVoulez-vous continuer?";
 
+"Are you sure you want to delete the selected calendar?"
+= "Are you sure you want to delete the selected calendar?";
+
 /* Legend */
 "Required participant" = "Participant obligatoire";
 "Optional participant" = "Participant facultatif";
index ca3933a0cdd7506fdce69b94a56447908931c47c..a7c0126f060302b677a72c7daccf147e50f5f3fa 100644 (file)
@@ -109,19 +109,4 @@ static NSMutableArray *yearMenuItems = nil;
   return yearMenuItem;
 }
 
-- (id) batchDeleteAction
-{
-  NSArray *ids;
-  SOGoAppointmentFolder *clientObject;
-
-  ids = [[self queryParameterForKey: @"ids"] componentsSeparatedByString: @"/"];
-  if (ids)
-    {
-      clientObject = [self clientObject];
-      [clientObject deleteEntriesWithIds: ids];
-    }
-
-  return self;
-}
-
 @end
index b411f6b4407ce7764009e53423a5289fa15fb4f7..e077176ab72882d7b7d713c031ce2f0b9b770741 100644 (file)
@@ -106,7 +106,7 @@ colorForNumber (unsigned int number)
   SOGoAppointmentFolder *folder;
   NSMutableDictionary *calendar;
   unsigned int count, max;
-  NSString *folderId, *folderName;
+  NSString *folderName;
   NSNumber *isActive;
 
   if (!calendars)
index c5afd5cc6e0c35e31d1b7cfadd02280865b285a2..6ee2a5afb701b41264c78a399c40ce4409cc8761 100644 (file)
              pageName    = "UIxCalUserRightsEditor";
              actionName  = "saveUserRights";
           };
+          editAttendees = {
+             protectedBy = "View";
+             pageName    = "UIxAttendeesEditor";
+          };
        };
      };
 
              pageName    = "UIxTaskEditor"; 
              actionName  = "new";
           };
-          batchDelete = {
-             protectedBy = "Delete Objects";
-             pageName    = "UIxCalMainView";
-             actionName  = "batchDelete";
-          };
-
           show = { 
              protectedBy = "View";
              pageName    = "UIxCalView"; 
              actionName  = "redirectForUIDs";
           };
-          batchDelete = {
-             protectedBy = "Delete Objects";
-             pageName    = "UIxCalMainView";
-             actionName  = "batchDelete";
-          };
-          editAttendees = {
-             protectedBy = "View";
-             pageName    = "UIxAttendeesEditor";
-          };
           userRights = {
              protectedBy = "ReadAcls";
              pageName    = "UIxCalUserRightsEditor";
              pageName    = "UIxAppointmentEditor"; 
              actionName  = "decline";
           };
-          editAttendees = {
-             protectedBy = "View";
-             pageName    = "UIxAttendeesEditor";
-          };
        };
      };
 
index d9638d34041169a3198218fc7695e6696ed28514..14e763516563679aa241cd6ee4708e4da13fc314 100644 (file)
   <script type="text/javascript" rsrc:src="skycalendar.js"><!-- space --></script>
   <script type="text/javascript" rsrc:src="UIxComponentEditor.js"><!-- space --></script>
 
+  <script type="text/javascript">
+    var activeCalendar = '<var:string value="clientObject.container.nameInContainer"/>';
+    var activeComponent = '<var:string value="clientObject.nameInContainer"/>';
+  </script>
+
   <div class="menu" id="privacy-menu">
     <ul id="itemPrivacyList">
       <var:foreach list="privacyClasses" item="item">
index 59244aed272bfc0668bd1e39ee87cbe466a16a20..ff1588e05186ec38ae6f47bcae8daecf47a2b761 100644 (file)
@@ -44,6 +44,7 @@
        </script>
        <script type="text/javascript" rsrc:src="events.js"><!-- space required --></script>
        <script type="text/javascript" rsrc:src="prototype.js"><!-- space required --></script>
+       <script type="text/javascript" rsrc:src="tablekit.js"><!-- space required --></script>
        <script type="text/javascript" rsrc:src="JavascriptAPIExtensions.js"><!-- space required --></script>
        <script type="text/javascript" rsrc:src="HTMLElement.js"><!-- space required --></script>
        <script type="text/javascript" rsrc:src="HTMLInputElement.js"><!-- space required --></script>
index 38ac3b24cfbaf884a359661440593ae5911805e0..3fd5439dd1ad697c2f0c46c4391f508b2fa7ee59 100644 (file)
               var:href="buttonInfo.link"
               var:target="buttonInfo.target"
               var:onclick="buttonInfo.onclick"
-              var:title="buttonInfo.tooltip"
+              var:title="buttonTooltip"
               ><span class="toolbarButton"
                 ><img class="buttonImage"
                   var:src="buttonImage"
-                  var:alt="buttonInfo.tooltip"
+                  var:alt="buttonTooltip"
                   /><var:if condition="hasMenu"
                   ><img class="buttonMenuArrow"
                     rsrc:src="arrow-dwn-sharp.gif"
-                    var:alt="buttonInfo.tooltip"
+                    var:alt="buttonTooltip"
                     /></var:if
                   ><br
                   /><span class="buttonLabel"
@@ -37,7 +37,7 @@
             ><span class="disabledToolbarButton"
               ><img class="buttonImage"
                 var:src="buttonImage"
-                var:alt="buttonInfo.tooltip"
+                var:alt="buttonTooltip"
                 /><br
                 /><span class="buttonLabel"
                 ><var:string
index a610e2332f444ca787a17526c29fe93c92205a83..5cdfff85fd8dba0020606ebabcd2cd7beb8e257b 100644 (file)
@@ -173,12 +173,12 @@ TABLE#contactsList
   width: 100%; }
 
 TABLE#contactsList TD
-{ white-space: nowrap;
-  width: 20%; }
+{ white-space: wrap;
+  /*width: 20%;*/ }
 
 TD#nameHeader,
 TD#mailHeader
-{ width: 30%; }
+{ /*width: 30%;*/ }
 
 TABLE#contactsList TD IMG
 {
@@ -245,6 +245,18 @@ DIV.contactColumn H4
 INPUT#searchValue:focus
 { color: #000; }
 
+TABLE#contactsList TD.resize-handle-active
+{ cursor: e-resize; }
+
+DIV.resize-handle
+{ cursor: e-resize;
+  width: 2px;
+  border-right: 1px solid #fff;
+  position: absolute;
+  top: 0;
+  left: 0;
+  max-height: 2em; }
+
 /* drag handles */
 DIV#dragHandle
 { 
index e5b841468be2e61dd942a988fc4f7b35fe6f06a4..b940720a9c3f3723bb2816d6f31541eb4b6672b9 100644 (file)
@@ -2,6 +2,7 @@
 
 var cachedContacts = new Array();
 var currentContactFolder = null;
+var savedColumnsWidth = null;
 
 var usersRightsWindowHeight = 200;
 var usersRightsWindowWidth = 450;
@@ -78,7 +79,7 @@ function configureContactsListHeaders(cells) {
       var currentCell = $(cells[i]);
       Event.observe(currentCell, "click",
                    onHeaderClick.bindAsEventListener(currentCell));
-      Event.observe(currentCell, "mousedown", listRowMouseDownHandler);
+      //Event.observe(currentCell, "mousedown", listRowMouseDownHandler);
    }
 }
 
@@ -88,11 +89,17 @@ function contactsListCallback(http) {
   if (http.readyState == 4
       && http.status == 200) {
     document.contactsListAjaxRequest = null;
-    div.innerHTML = http.responseText;
+    div.update(http.responseText);
 
     var table = $("contactsList");
-    if (table)
+    if (table) {
+       TableKit.Resizable.init(table);
+       if (savedColumnsWidth != null) {
+        // Restore columns width
+        table.setColumnsWidth(savedColumnsWidth);
+       }
        configureContactsListHeaders(table.tBodies[0].rows[0].cells);
+    }
 
     if (sorting["attribute"] && sorting["attribute"].length > 0) {
        var sortHeader;
@@ -147,11 +154,10 @@ function onContactFoldersContextMenu(event) {
   $(this).select();
 }
 
-function onContactContextMenu(event, element) {
+function onContactContextMenu(event, element) { log ("onContactContextMenu");
   var menu = $("contactMenu");
-  //Event.observe(menu, "hideMenu", onContactContextMenuHide, false);
+
   Event.observe(menu, "mousedown", onContactContextMenuHide, false);
-  //document.documentElement.onclick = onContactContextMenuHide;
   popupMenu(event, "contactMenu", element);
 
   var topNode = $("contactsList");
@@ -290,9 +296,19 @@ function onMenuEditContact(event) {
 
 function onMenuWriteToContact(event) {
    var contactId = document.menuTarget.getAttribute('id');
+   var contactRow = $(contactId);
+   var emailCell = contactRow.down('td', 1);
+
+   if (!emailCell.firstChild) { // .nodeValue is the contact email address
+     window.alert(labels["The selected contact has no email address."].decodeEntities());
+     return false;
+   }
 
    openMailComposeWindow(ApplicationBaseURL + currentContactFolder
                         + "/" + contactId + "/write");
+
+   if (document.body.hasClassName("popup"))
+     window.close();
 }
 
 function onMenuDeleteContact(event) {
@@ -314,10 +330,22 @@ function onToolbarEditSelectedContacts(event) {
 function onToolbarWriteToSelectedContacts(event) {
   var contactsList = $('contactsList');
   var rows = contactsList.getSelectedRowsId();
+  var rowsWithEmail = 0;
 
-  for (var i = 0; i < rows.length; i++)
-    openMailComposeWindow(ApplicationBaseURL + currentContactFolder
-                          + "/" + rows[i] + "/write");
+  for (var i = 0; i < rows.length; i++) {
+    var emailCell = $(rows[i]).down('td', 1);
+    if (emailCell.firstChild) { // .nodeValue is the contact email address
+      rowsWithEmail++;
+      openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+                           + "/" + rows[i] + "/write");
+    }
+  }
+  
+  if (rowsWithEmail == 0) {
+    window.alert(labels["The selected contact has no email address."].decodeEntities());
+  }
+  else if (document.body.hasClassName("popup"))
+    window.close();
 
   return false;
 }
@@ -390,6 +418,7 @@ function onHeaderClick(event) {
       sorting["ascending"] = true;
    }
 
+   savedColumnsWidth = this.up('table').getColumnsWidth();
    refreshCurrentFolder();
 
    preventDefault(event);
@@ -478,11 +507,15 @@ function appendAddressBook(name, folder) {
     folder = accessToSubscribedFolder(folder);
   else
     folder = "/" + name;
-  var li = document.createElement("li");
-  $("contactFolders").appendChild(li);
-  li.setAttribute("id", folder);
-  li.appendChild(document.createTextNode(name));
-  setEventsOnContactFolder(li);
+  if ($(folder))
+    window.alert(clabels["You have already subscribed to that folder!"]);
+  else {
+    var li = document.createElement("li");
+    $("contactFolders").appendChild(li);
+    li.setAttribute("id", folder);
+    li.appendChild(document.createTextNode(name));
+    setEventsOnContactFolder(li);
+  }
 }
 
 function newFolderCallback(http) {
index 7979e41fb7916a313fd811e5aa52eef36023d9e7..e029cd8ba7f92a350f8ff2641df740474eaecb28 100644 (file)
@@ -34,5 +34,28 @@ Element.addMethods({
          node.select();
       }
     }
+  },
+
+  getColumnsWidth: function(element) {
+    element = $(element);
+    var widths = new Array();
+    if (element.tagName == 'TABLE') {
+      var cells = TableKit.getHeaderCells(element);
+      for (var i = 0; i < cells.length; i++) {
+       widths[i] = $(cells[i]).getWidth();
+      }
+    }
+    return widths;
+  },
+
+  setColumnsWidth: function(element, widths) {
+    element = $(element);
+    if (element.tagName == 'TABLE') {
+      for (var i = 0; i < widths.length; i++) {
+       TableKit.Resizable.resize(element, i, widths[i]);
+      }
+    }
   }
+
+
 }); // Element.addMethods
index 18798df294316506647e5c9cc53e89d7bdabc1d7..6b2e4773a2f36e29559b5ee57226a6bf9460269b 100644 (file)
@@ -14,7 +14,7 @@
   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
+  License along with OGo; see the file COPYING.  If not, write toge the
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
@@ -312,8 +312,7 @@ INPUT#editDraftButton
 }
 
 TABLE.mailer_fieldtable
-{
-  top: 0px;
+{ top: 0px;
   left: 0px;
   padding-top: .5em;
   padding-bottom: .5em;
@@ -321,7 +320,7 @@ TABLE.mailer_fieldtable
   overflow-x: hidden;
   border-bottom: 1px solid #808080;
   background: #d4d0c8;
-}
+  width: 100%; }
 
 DIV.mailer_mailcontent
 {
@@ -478,9 +477,7 @@ TABLE#addr_table
 }
 
 TABLE#messageList
-{ display: block;
-  position: relative;
-  width: 100%; }
+{ /*width: 100%;*/ }
 
 TABLE#messageList TD
 { height: 1.2em; }
@@ -494,19 +491,20 @@ TD#subjectHeader,
 TABLE#messageList TD.tbtv_subject_headercell,
 TABLE#messageList TD.mailer_unreadmailsubject,
 TABLE#messageList TD.mailer_readmailsubject
-{ width: 40%;
+{ /*width: 40%;*/
   min-width: 40%; }
 
 TD#fromHeader,
 TABLE#messageList TD.tbtv_from_headercell,
 TABLE#messageList TD.messageAddressColumn
-{ width: 35%;
+{ /*width: 35%;*/
+  min-width: 35%;
   overflow: hidden; }
 
 TD#dateHeader,
 TABLE#messageList TD.tbtv_date_headercell,
 TABLE#messageList TD.messageDateColumn
-{ width: 25%;
+{ /*width: 25%;*/
   overflow: hidden; }
 
 TABLE#messageList TR._selected TD
@@ -520,6 +518,18 @@ TABLE#messageList TR._deleted TD
   text-decoration: line-through;
 }
 
+TABLE#messageList TD.resize-handle-active
+{ cursor: e-resize; }
+
+DIV.resize-handle
+{ cursor: e-resize;
+  width: 2px;
+  border-right: 1px solid #fff;
+  position: absolute;
+  top: 0;
+  left: 0;
+  max-height: 2em; }
+
 /* drag handles */
 DIV#verticalDragHandle
 {
index 6b626482bf2300c529ec5efc548179dca6840b80..074a94f944c3167deca28fc5eff81d87ca9d44cf 100644 (file)
@@ -241,7 +241,7 @@ function uixDeleteSelectedMessages(sender) {
       deleteCachedMessage(messageId);
       if (currentMessages[currentMailbox] == rowId) {
        var div = $('messageContent');
-       div.innerHTML = "";
+       div.update();
        currentMessages[currentMailbox] = null;
       }
     }
@@ -280,7 +280,7 @@ function moveMessages(rowIds, folder) {
       deleteCachedMessage(messageId);
       if (currentMessages[currentMailbox] == rowIds[i]) {
        var div = $('messageContent');
-       div.innerHTML = "";
+       div.update();
        currentMessages[currentMailbox] = null;
       }
     }
@@ -334,7 +334,7 @@ function onMailboxTreeItemClick(event) {
   currentMailboxType = this.parentNode.getAttribute("datatype");
   if (currentMailboxType == "account" || currentMailboxType == "additional") {
     currentMailbox = mailbox;
-    $("messageContent").innerHTML = "";
+    $("messageContent").update();
     var body = $("messageList").tBodies[0];
     for (var i = body.rows.length; i > 0; i--)
       body.deleteRow(i-1);
@@ -380,8 +380,8 @@ function openMailbox(mailbox, reload, idx) {
     currentMailbox = mailbox;
     var url = ApplicationBaseURL + mailbox + "/view?noframe=1";
     var messageContent = $("messageContent");
-    messageContent.innerHTML = '';
-
+    messageContent.update();
+   
     var currentMessage;
     if (!idx) {
       currentMessage = currentMessages[mailbox];
@@ -401,7 +401,6 @@ function openMailbox(mailbox, reload, idx) {
              + "&asc=" + sorting["ascending"]);
     if (idx)
       url += "&idx=" + idx;
-
     if (document.messageListAjaxRequest) {
       document.messageListAjaxRequest.aborted = true;
       document.messageListAjaxRequest.abort();
@@ -438,8 +437,11 @@ function messageListCallback(http) {
    
   if (http.readyState == 4
       && http.status == 200) {
-    document.messageListAjaxRequest = null;
-    div.innerHTML = http.responseText;
+    document.messageListAjaxRequest = null;    
+    div.update(http.responseText);
+
+    TableKit.Resizable.init($('messageList'));
+
     var selected = http.callbackData;
     if (selected) {
       var row = $("row_" + selected);
@@ -447,6 +449,7 @@ function messageListCallback(http) {
        row.select();
     }
     configureMessageListEvents();
+    
     if (sorting["attribute"] && sorting["attribute"].length > 0) {
       var sortHeader;
       if (sorting["attribute"] == "subject")
@@ -652,7 +655,7 @@ function loadMessage(idx) {
     markMailInWindow(window, idx, true);
   } else {
     var div = $('messageContent');
-    div.innerHTML = cachedMessage['text'];
+    div.update(cachedMessage['text']);
     cachedMessage['time'] = (new Date()).getTime();
     document.messageAjaxRequest = null;
     configureLinksInMessage();
@@ -705,7 +708,7 @@ function messageCallback(http) {
   if (http.readyState == 4
       && http.status == 200) {
     document.messageAjaxRequest = null;
-    div.innerHTML = http.responseText;
+    div.update(http.responseText);
     configureLinksInMessage();
       
     if (http.callbackData) {
@@ -864,7 +867,7 @@ function onHeaderClick(event) {
 
   refreshCurrentFolder();
 
-  preventDefault(event);
+  Event.stop(event);
 }
 
 function refreshCurrentFolder() {
@@ -957,8 +960,8 @@ function configureMessageListHeaders(cells) {
   for (var i = 0; i < cells.length; i++) {
     var currentCell = $(cells[i]);
     Event.observe(currentCell, "click",
-                 onHeaderClick.bindAsEventListener(currentCell));
-    Event.observe(currentCell, "mousedown", listRowMouseDownHandler);
+                 onHeaderClick.bindAsEventListener(currentCell));
+    //Event.observe(currentCell, "mousedown", listRowMouseDownHandler);
   }
 }
 
@@ -966,9 +969,10 @@ function configureMessageListEvents() {
   var messageList = $("messageList");
   if (messageList) {
     Event.observe(messageList, "mousedown",
-                 onMessageSelectionChange.bindAsEventListener(messageList));
+                 onMessageSelectionChange.bindAsEventListener(messageList));
 
     configureMessageListHeaders(messageList.tHead.rows[0].cells);
+
     var cell = messageList.tHead.rows[1].cells[0];
     if ($(cell).hasClassName("tbtv_navcell")) {
       var anchors = $(cell).childNodesWithTag("a");
@@ -1059,9 +1063,7 @@ function openInbox(node) {
 
 function initMailer(event) {
   if (!document.body.hasClassName("popup")) {
-    configureMessageListEvents();
     initDnd();
-    currentMailbox = "/" + accounts[0] + "/folderINBOX";
     initMailboxTree();
   }
 }
@@ -1097,7 +1099,7 @@ function initMailboxTree() {
 }
 
 function updateMailboxTreeInPage() {
-  $("folderTreeContent").innerHTML = mailboxTree;
+  $("folderTreeContent").update(mailboxTree);
 
   var inboxFound = false;
   var tree = $("mailboxTree");
index 7c992039a38d2b073db895b2e7684f7956e69db6..199a1a87cc9e4983ed80f9f806812dfac5f002d0 100644 (file)
@@ -196,25 +196,26 @@ function modifyEventCallback(http) {
 }
 
 function deleteEventCallback(http) {
-  if (http.readyState == 4
-      && http.status == 200) {
-    var nodes = http.callbackData;
-    for (var i = 0; i < nodes.length; i++) {
-      var node = $(nodes[i]);
-      if (node)
-        node.parentNode.removeChild(node);
-    }
-    if (eventsToDelete.length)
-      _batchDeleteEvents();
-    else {
-      document.deleteEventAjaxRequest = null;
-      refreshEvents();
-      refreshTasks();
-      changeCalendarDisplay();
+  if (http.readyState == 4) {
+    if (isHttpStatus204(http.status)) {
+      var nodes = http.callbackData;
+      for (var i = 0; i < nodes.length; i++) {
+       var node = $(nodes[i]);
+       if (node)
+         node.parentNode.removeChild(node);
+      }
+      if (eventsToDelete.length)
+       _batchDeleteEvents();
+      else {
+       document.deleteEventAjaxRequest = null;
+       refreshEvents();
+       refreshTasks();
+       changeCalendarDisplay();
+      }
     }
+    else
+      log ("deleteEventCallback Ajax error");
   }
-  else
-    log ("deleteEventCallback Ajax error");
 }
 
 function editDoubleClickedEvent(event) {
@@ -610,9 +611,17 @@ function drawCalendarEvent(eventData, sd, ed) {
    var viewEndDate = ed.asDate();
 
    var startDate = new Date();
-   startDate.setTime(eventData[4] * 1000 + (1000 * UTCOffset));
    var endDate = new Date();
-   endDate.setTime(eventData[5] * 1000 + (1000 * UTCOffset));
+   if (eventData[7] == 0) {
+     startDate.setTime(eventData[4] * 1000 + (1000 * UTCOffset));
+     endDate.setTime(eventData[5] * 1000 + (1000 * UTCOffset));
+   }
+   else {
+     startDate.setTime(eventData[4] * 1000);
+     endDate.setTime(eventData[5] * 1000);
+   }
+
+//    log ("s: " + startDate+ "; e: " + endDate);
 
    var days = startDate.daysUpTo(endDate);
 
@@ -1290,7 +1299,8 @@ function getMenus() {
                                       editEvent, deleteEvent, "-",
                                       onSelectAll, "-",
                                       null, null);
-   menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
+   menus["calendarsMenu"] = new Array(onCalendarNew, onCalendarRemove,
+                                     "-", null, null, "-",
                                      null, "-", onMenuSharing);
    menus["searchMenu"] = new Array(setSearchCriteria);
 
@@ -1364,55 +1374,58 @@ function appendCalendar(folderName, folder) {
 
 //   log ("append: " + folderName + "; folder: " + folder);
 
-  var calendarList = $("calendarList");
-  var lis = calendarList.childNodesWithTag("li");
-  var color = indexColor(lis.length + 100);
-  //log ("color: " + color);
-
-  var li = document.createElement("li");
-  calendarList.appendChild(li);
-
-  var checkBox = document.createElement("input");
-  checkBox.setAttribute("type", "checkbox");
-  li.appendChild(checkBox);
-   
-  li.appendChild(document.createTextNode(" "));
-
-  var colorBox = document.createElement("div");
-  li.appendChild(colorBox);
-  li.appendChild(document.createTextNode(" " + folderName));
-  colorBox.appendChild(document.createTextNode("OO"));
-
-  li.setAttribute("id", folder);
-  Event.observe(li, "mousedown",  listRowMouseDownHandler);
-  Event.observe(li, "click",  onRowClick);
-  $(checkBox).addClassName("checkBox");
-
-  Event.observe(checkBox, "click",
-               updateCalendarStatus.bindAsEventListener(checkBox));
-
-  $(colorBox).addClassName("colorBox");
-  if (color)
-    $(colorBox).setStyle({color: color,
-                         backgroundColor: color});
-
-  var url = URLForFolderID(folder) + "/canAccessContent";
-  triggerAjaxRequest(url, calendarEntryCallback, folder);
-
-  if (!document.styleSheets) return;
-  var theRules = new Array();
-  var lastSheet = document.styleSheets[document.styleSheets.length - 1];
-  if (lastSheet.insertRule) { // Mozilla
-    lastSheet.insertRule('.calendarFolder' + folder.substr(1) + ' {'
-                        + ' background-color: '
-                        + color
-                        + ' !important; }', 0);
-  }
-  else { // IE
-    lastSheet.addRule('.calendarFolder' + folder.substr(1),
-                     ' background-color: '
-                     + color
-                     + ' !important; }');
+  if ($(folder))
+    window.alert(clabels["You have already subscribed to that folder!"]);
+  else {
+    var calendarList = $("calendarList");
+    var lis = calendarList.childNodesWithTag("li");
+    var color = indexColor(lis.length + 100);
+    //log ("color: " + color);
+
+    var li = document.createElement("li");
+    calendarList.appendChild(li);
+
+    var checkBox = document.createElement("input");
+    checkBox.setAttribute("type", "checkbox");
+    li.appendChild(checkBox);
+    li.appendChild(document.createTextNode(" "));
+
+    var colorBox = document.createElement("div");
+    li.appendChild(colorBox);
+    li.appendChild(document.createTextNode(" " + folderName));
+    colorBox.appendChild(document.createTextNode("OO"));
+
+    li.setAttribute("id", folder);
+    Event.observe(li, "mousedown",  listRowMouseDownHandler);
+    Event.observe(li, "click",  onRowClick);
+    $(checkBox).addClassName("checkBox");
+
+    Event.observe(checkBox, "click",
+                 updateCalendarStatus.bindAsEventListener(checkBox));
+
+    $(colorBox).addClassName("colorBox");
+    if (color)
+      $(colorBox).setStyle({color: color,
+                           backgroundColor: color});
+
+    var url = URLForFolderID(folder) + "/canAccessContent";
+    triggerAjaxRequest(url, calendarEntryCallback, folder);
+    
+    if (!document.styleSheets) return;
+    var theRules = new Array();
+    var lastSheet = document.styleSheets[document.styleSheets.length - 1];
+    if (lastSheet.insertRule) { // Mozilla
+      lastSheet.insertRule('.calendarFolder' + folder.substr(1) + ' {'
+                          + ' background-color: '
+                          + color
+                          + ' !important; }', 0);
+    }
+    else { // IE
+      lastSheet.addRule('.calendarFolder' + folder.substr(1),
+                       ' background-color: '
+                       + color
+                       + ' !important; }');
+    }
   }
 }
 
index af61b807ea25ae044c421c87332a825b695ea61b..a00b4d16d4118fe8f7c68be84f92863ca810c71f 100644 (file)
@@ -1,7 +1,7 @@
 function onPopupAttendeesWindow(event) {
    if (event)
       preventDefault(event);
-   window.open(ApplicationBaseURL + "editAttendees", null, 
+   window.open(ApplicationBaseURL + "/editAttendees", null, 
                "width=803,height=573");
 
    return false;
@@ -170,7 +170,7 @@ function onComponentEditorLoad(event) {
 
    var menuItems = $("itemPrivacyList").childNodesWithTag("li");
    for (var i = 0; i < menuItems.length; i++)
-      Event.observe(menuItems[i], "mouseup",
+      Event.observe(menuItems[i], "mousedown",
                    onMenuSetClassification.bindAsEventListener(menuItems[i]),
                    false);
 }
index 07f979f676d74a3d24793f9e423ee10251c55127..59077cd8e1aa726c7d8478c44cb4e8976711bbaa 100644 (file)
@@ -54,13 +54,11 @@ LABEL
   margin-left: .5em; }
 
 TABLE
-{ display: block;
-  table-layout: fixed;
+{ table-layout: fixed;
   border-spacing: 0px; }
 
 TABLE TD
-{ white-space: nowrap;
-  padding-left: .25em;
+{ padding-left: .25em;
   padding-right: .25em; }
 
 a:link
@@ -94,7 +92,7 @@ div#header
 { margin-left: 5px;
   margin-right: 5px;
   padding: 0;
-  border-bottom: 1px solid #000000; }
+  border-bottom: 1px solid #000; }
 
 div#header img.headerlogo
 { float: right; 
@@ -354,6 +352,19 @@ SPAN.toolbarButton:active
 .menu LI.submenu:hover, .menu LI.submenu-selected
 { background-image: url('submenu-active.gif') !important; }
 
+/* live search popup menu */
+UL#searchOptions LI
+{ list-style-position: inside;
+  list-style-image: url("menu-nocheck.gif");
+  padding: 1px 3px;
+  margin: px; }
+
+UL#searchOptions LI._chosen
+{ list-style-image: url("menu-check.gif"); }
+
+UL#searchOptions LI._chosen:hover
+{ list-style-image: url("menu-check-hover.gif"); }
+
 DIV#logConsole
 { position: absolute;
   overflow: auto;
@@ -415,15 +426,13 @@ TD.tbtv_headercell:active
 
 TD.headerCell SPAN,
 td.tbtv_headercell SPAN
-{ float: left;
-  width: 100%; }
+{ float: left; }
 
 td.tbtv_headercell a
 { cursor: default;
   margin: 0px auto;
   display: block;
-  color: black;
-  width: 100%; }
+  color: black; }
 
 td.tbtv_headercell a:hover
 { margin: 0px auto;
@@ -452,8 +461,7 @@ TR.tableview TD
   padding-right: .3em; }
 
 TD.headerDateTime
-{ width: 30em;
-  min-width: 30em; }
+{ min-width: 30em; }
 
 TD.headerTitle
 { width: 30%; }
@@ -471,8 +479,7 @@ td img.tbtv_sortcell
 
 TD.subjectCell,
 td.tbtv_subject_headercell
-{ overflow: hidden;
-  width: auto; }
+{ overflow: hidden; }
 
 /* drag handles */
 DIV.dragHandle
index 3a4462c4d79d87560d66ab30b216de6387ac8e34..9a7c60538391a03b15e13d27a4ca81df83ed43d9 100644 (file)
@@ -222,7 +222,7 @@ function openContactWindow(url, wId) {
   return w;
 }
 
-function openMailComposeWindow(url, wId) {
+function openMailComposeWindow(url, wId) { log (url);
   if (!wId)
     wId = "" + (new Date().getTime());
   var w = window.open(url, wId,
@@ -592,7 +592,7 @@ function onBodyClickMenuHandler(event) {
    preventDefault(event);
 }
 
-function hideMenu(menuNode) { //log ("hideMenu");
+function hideMenu(menuNode) {
   var onHide;
 
   if (menuNode.submenu) {
@@ -605,17 +605,17 @@ function hideMenu(menuNode) { //log ("hideMenu");
   if (menuNode.parentMenuItem) {
     menuNode.parentMenuItem.setAttribute('class', 'submenu');
     menuNode.parentMenuItem = null;
-    menuNode.parentMenu.setAttribute('onmousemove', null);
+    Event.stopObserving(menuNode, 'mousemove', checkDropDown);
     menuNode.parentMenu.submenuItem = null;
     menuNode.parentMenu.submenu = null;
     menuNode.parentMenu = null;
   }
 
-  if (document.createEvent) {
+  if (document.createEvent) { // Safari & Mozilla
     var onhideEvent;
     if (isSafari())
       onhideEvent = document.createEvent("UIEvents");
-    else // Mozilla
+    else
       onhideEvent = document.createEvent("Events");
     onhideEvent.initEvent("mousedown", false, true);
     menuNode.dispatchEvent(onhideEvent);
@@ -629,7 +629,6 @@ function onMenuEntryClick(event) {
   var node = event.target;
 
   id = getParentMenu(node).menuTarget;
-//   log("clicked " + id + "/" + id.tagName);
 
   return false;
 }
@@ -756,7 +755,7 @@ function dropDownSubmenu(event) {
             + parentNode.cascadeLeftOffset()))
         menuLeft = - submenuNode.offsetWidth + 3;
       
-      parentNode.setAttribute('onmousemove', 'checkDropDown(event);');
+      Event.observe(parentNode, "mousemove", checkDropDown);
       node.setAttribute('class', 'submenu-selected');
       submenuNode.setStyle({ top: menuTop + "px",
                                     left: menuLeft + "px",
@@ -780,7 +779,7 @@ function checkDropDown(event) {
       hideMenu(parentMenu.submenu);
       parentMenu.submenu = null;
       parentMenu.submenuItem = null;
-      parentMenu.setAttribute('onmousemove', null);
+      Event.stopObserving(parentMenu, 'mousemove', checkDropDown);
     }
   }
 }
@@ -818,6 +817,11 @@ function setSearchCriteria(event) {
 
   searchValue.setAttribute("ghost-phrase", this.innerHTML);
   searchCriteria.value = this.getAttribute('id');
+  
+  if (this.parentNode.chosenNode)
+    this.parentNode.chosenNode.removeClassName("_chosen");
+  this.addClassName("_chosen");
+  this.parentNode.chosenNode = this;
 }
 
 function checkSearchValue(event) {
@@ -835,6 +839,7 @@ function onSearchChange() {
 
 function configureSearchField() {
    var searchValue = $("searchValue");
+   var searchOptions = $("searchOptions");
 
    if (!searchValue) return;
 
@@ -848,6 +853,13 @@ function configureSearchField() {
                 onSearchFocus.bindAsEventListener(searchValue));
    Event.observe(searchValue, "keydown",
                 onSearchKeyDown.bindAsEventListener(searchValue));
+
+   if (!searchOptions) return;
+   
+   // Set the checkmark to the first option
+   var firstOption = searchOptions.down('li');
+   firstOption.addClassName("_chosen");
+   searchOptions.chosenNode = firstOption;
 }
 
 function onSearchMouseDown(event) {
@@ -875,7 +887,7 @@ function onSearchFocus() {
 
 function onSearchBlur(event) {
    var ghostPhrase = this.getAttribute("ghost-phrase");
-   //log ("search blur: '" + this.value + "'");
+
    if (!this.value) {
     this.setAttribute("modified", "");
     this.setStyle({ color: "#aaa" });
@@ -901,7 +913,7 @@ function onSearchFormSubmit(event) {
    var searchValue = $("searchValue");
    var searchCriteria = $("searchCriteria");
    var ghostPhrase = searchValue.getAttribute('ghost-phrase');
-
+   
    if (searchValue.value == ghostPhrase) return;
 
    search["criteria"] = searchCriteria.value;