]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1400 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 22 Apr 2008 14:55:25 +0000 (14:55 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 22 Apr 2008 14:55:25 +0000 (14:55 +0000)
33 files changed:
ChangeLog
Main/SOGo.m
SoObjects/Appointments/SOGoAppointmentFolder.h
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/SOGo/NSString+Utilities.h
SoObjects/SOGo/NSString+Utilities.m
SoObjects/SOGo/SOGoGCSFolder.h
SoObjects/SOGo/SOGoGCSFolder.m
SoObjects/SOGo/SOGoObject.m
SoObjects/SOGo/SOGoUser.h
UI/Common/UIxFolderActions.h
UI/Common/UIxFolderActions.m
UI/Common/product.plist
UI/SOGoUI/UIxJSClose.m
UI/Scheduler/GNUmakefile
UI/Scheduler/UIxCalendarProperties.h [new file with mode: 0644]
UI/Scheduler/UIxCalendarProperties.m [new file with mode: 0644]
UI/Scheduler/UIxCalendarSelector.m
UI/Scheduler/UIxColorPicker.h [new file with mode: 0644]
UI/Scheduler/UIxColorPicker.m [new file with mode: 0644]
UI/Scheduler/product.plist
UI/Templates/SchedulerUI/UIxCalendarProperties.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxColorPicker.wox [new file with mode: 0644]
UI/Templates/UIxJSClose.wox
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxCalendarProperties.css [new file with mode: 0644]
UI/WebServerResources/UIxCalendarProperties.js [new file with mode: 0644]
UI/WebServerResources/UIxColorPicker.js [new file with mode: 0644]
UI/WebServerResources/js_color_picker_v2.css [new file with mode: 0644]
UI/WebServerResources/js_color_picker_v2.js [new file with mode: 0644]
UI/WebServerResources/slider_handle.gif [new file with mode: 0644]
UI/WebServerResources/tab_.gif [deleted file]
UI/WebServerResources/tab_selected.gif [deleted file]

index 243b773d1df3b5249e6e2f9cfd21062f1d28bba4..ef99e9b1281b506e8add49ecccf82d430c269a8c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-04-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder
+       -setDavDisplayName:newName]): deny the renaming of the folder if
+       not owner.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject
+       -davSetProperties:setPropsremovePropertiesNamed:removedPropsinContext:localContext]):
+       certain properties should be authorized when not owner.
+
+2008-04-21  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxColorPicker.[hm]: new class module that
+       implements a javascript-based color picker.
+
+       * UI/Scheduler/UIxCalendarProperties.[hm]: new class module that
+       implements the interface for renaming and recoloring the
+       calendars.
+
 2008-04-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/MailPartViewers/UIxMailPartHTMLViewer.m
index f61c14668256dbd3d1df126574e38f27a6b28a15..afb19b095bf06301840945c788400c385a64d516 100644 (file)
@@ -392,7 +392,6 @@ static BOOL debugObjectAllocation = NO;
   static NSArray *runLoopModes = nil;
   WOResponse *resp;
 
-//   sleep (1);
   cache = [SOGoCache sharedCache];
   resp = [super dispatchRequest: _request];
   [SOGoCache killCache];
index c359f65e01ec6af0a39bd488bb2c071006308a4e..8b0d97ed5919a3a91339164022e089f9c17721fe 100644 (file)
@@ -58,6 +58,9 @@
 
 - (BOOL) isActive;
 
+- (NSString *) calendarColor;
+- (void) setCalendarColor: (NSString *) newColor;
+
 /* selection */
 
 - (NSArray *) calendarUIDs;
index b7760034757203cda30973a0b9304330ce372ea8..bf618a8bf119314038eabddb6c75fc2c1dda937f 100644 (file)
@@ -63,6 +63,8 @@
 
 #import "SOGoAppointmentFolder.h"
 
+#define defaultColor @"#AAAAAA"
+
 #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY
 @interface NSDate(UsedPrivates)
 - (id)initWithTimeIntervalSince1970:(NSTimeInterval)_interval;
@@ -130,6 +132,46 @@ static NSNumber   *sharedYes = nil;
   [super dealloc];
 }
 
+- (NSString *) calendarColor
+{
+  NSUserDefaults *settings;
+  NSDictionary *colors;
+  NSString *color;
+
+  settings = [[context activeUser] userSettings];
+  colors = [[settings objectForKey: @"Calendar"]
+            objectForKey: @"FolderColors"];
+  color = [colors objectForKey: [self folderReference]];
+  if (!color)
+    color = defaultColor;
+
+  return color;
+}
+
+- (void) setCalendarColor: (NSString *) newColor
+{
+  NSUserDefaults *settings;
+  NSMutableDictionary *calendarSettings;
+  NSMutableDictionary *colors;
+
+  settings = [[context activeUser] userSettings];
+  calendarSettings = [settings objectForKey: @"Calendar"];
+  if (!calendarSettings)
+    {
+      calendarSettings = [NSMutableDictionary dictionary];
+      [settings setObject: calendarSettings
+               forKey: @"Calendar"];
+    }
+  colors = [calendarSettings objectForKey: @"FolderColors"];
+  if (!colors)
+    {
+      colors = [NSMutableDictionary dictionary];
+      [calendarSettings setObject: colors forKey: @"FolderColors"];
+    }
+  [colors setObject: newColor forKey: [self folderReference]];
+  [settings synchronize];
+}
+
 /* logging */
 
 - (id) debugLogger
@@ -561,6 +603,34 @@ static NSNumber   *sharedYes = nil;
   return ns;
 }
 
+- (NSString *) davCalendarColor
+{
+  NSString *color;
+
+  color = [[self calendarColor] uppercaseString];
+
+  return [NSString stringWithFormat: @"%@FF", color];
+}
+
+- (NSException *) setDavCalendarColor: (NSString *) newColor
+{
+  NSException *error;
+  NSString *realColor;
+
+  if ([newColor length] == 9
+      && [newColor hasPrefix: @"#"])
+    {
+      realColor = [newColor substringToIndex: 7];
+      [self setCalendarColor: realColor];
+      error = nil;
+    }
+  else
+    error = [NSException exceptionWithHTTPStatus: 400
+                        reason: @"Bad color format (should be '#XXXXXXXX')."];
+
+  return error;
+}
+
 - (id) davCalendarQuery: (id) queryContext
 {
   WOResponse *r;
index 75bc6dc970cb1e0660724dec06a9dd8d660d5077..548cb29479bf8a50c25dd763b42322689d5196f1 100644 (file)
@@ -37,6 +37,7 @@
 - (NSString *) urlWithoutParameters;
 
 - (NSString *) davMethodToObjC;
+- (NSString *) davSetterName;
 - (NSDictionary *) asDavInvocation;
 
 - (NSString *) stringByDetectingURLs;
index ff0c38d036b5cd02aa537d0197d7ac1477a55df9..857fe71c87517f1310c8818c4d260edd98eb197a 100644 (file)
@@ -111,6 +111,18 @@ static NSMutableCharacterSet *urlStartChars = nil;
   return newName;
 }
 
+- (NSString *) davSetterName
+{
+  unichar firstLetter;
+  NSString *firstString;
+
+  firstLetter = [self characterAtIndex: 0];
+  firstString = [[NSString stringWithCharacters: &firstLetter length: 1]
+                 uppercaseString];
+  return [NSString stringWithFormat: @"set%@%@:",
+                  firstString, [self substringFromIndex: 1]];
+}
+
 - (NSDictionary *) asDavInvocation
 {
   NSMutableDictionary *davInvocation;
index 6a89dd4b2dac0d72bf3c08308e547be1e05b2a09..54214dff2b4626ee9e9ed8b5cb13d5ba8a0a0ead 100644 (file)
@@ -59,6 +59,8 @@
 - (GCSFolder *) ocsFolderForPath: (NSString *)_path;
 - (GCSFolder *) ocsFolder;
 
+- (NSString *) folderReference;
+
 /* lower level fetches */
 - (BOOL) nameExistsInFolder: (NSString *) objectName;
 
index 4fea87a1bbf79fe810241141b63af77e048b1061..e3d7c56ce8bf776ce134239eb5011d47a604f763 100644 (file)
@@ -227,11 +227,62 @@ static BOOL sendFolderAdvisories = NO;
   return [nameInContainer isEqualToString: @"personal"];
 }
 
+- (NSString *) folderReference
+{
+  NSString *login, *reference, *realName;
+  NSArray *nameComponents;
+
+  login = [[context activeUser] login];
+  if ([owner isEqualToString: login])
+    reference = nameInContainer;
+  else
+    {
+      nameComponents = [nameInContainer componentsSeparatedByString: @"_"];
+      if ([nameComponents count] > 1)
+       realName = [nameComponents objectAtIndex: 1];
+      else
+       realName = nameInContainer;
+
+      reference = [NSString stringWithFormat: @"%@:%@/%@",
+                           owner,
+                           [container nameInContainer],
+                           realName];
+    }
+
+  return reference;
+}
+
 - (NSString *) davDisplayName
 {
   return [self displayName];
 }
 
+- (NSException *) setDavDisplayName: (NSString *) newName
+{
+  NSException *error;
+  NSArray *currentRoles;
+
+  currentRoles = [[context activeUser] rolesForObject: self
+                                      inContext: context];
+  if ([currentRoles containsObject: SoRole_Owner])
+    {
+      if ([newName length])
+       {
+         [self renameTo: newName];
+         error = nil;
+       }
+      else
+       error = [NSException exceptionWithHTTPStatus: 400
+                            reason: [NSString stringWithFormat:
+                                                @"Empty string"]];
+    }
+  else
+    error = [NSException exceptionWithHTTPStatus: 403
+                        reason: @"Modification denied."];
+
+  return error;
+}
+
 - (GCSFolder *) ocsFolder
 {
   GCSFolder *folder;
@@ -449,8 +500,7 @@ static BOOL sendFolderAdvisories = NO;
       else
        folder = [realFolderPath objectAtIndex: 0];
 
-      subscriptionPointer = [NSString stringWithFormat: @"%@:%@/%@",
-                                     owner, baseFolder, folder];
+      subscriptionPointer = [self folderReference];
       if (reallyDo)
        [folderSubscription addObjectUniquely: subscriptionPointer];
       else
@@ -524,33 +574,6 @@ static BOOL sendFolderAdvisories = NO;
               inContext: queryContext];
 }
 
-- (NSException *) davSetProperties: (NSDictionary *) setProps
-            removePropertiesNamed: (NSDictionary *) removedProps
-                        inContext: (WOContext *) localContext
-{
-  NSString *newDisplayName;
-  NSException *exception;
-  NSArray *currentRoles;
-
-  currentRoles = [[localContext activeUser] rolesForObject: self
-                                           inContext: localContext];
-  if ([currentRoles containsObject: SoRole_Owner])
-    {
-      newDisplayName = [setProps objectForKey: @"davDisplayName"];
-      if ([newDisplayName length])
-       {
-         [self renameTo: newDisplayName];
-         exception = nil;
-       }
-      else
-       exception = [NSException exceptionWithHTTPStatus: 404];
-    }
-  else
-    exception = [NSException exceptionWithHTTPStatus: 403];
-
-  return exception;
-}
-
 /* acls as a container */
 
 - (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
index 64f1293fce2c7975c0fc92320e8a5f90c8c79539..678f6a3c188a57b8a9018c54ffc45ec7d2918aa0 100644 (file)
@@ -1342,4 +1342,37 @@ static BOOL sendACLAdvisories = NO;
   return r;
 }
 
+- (NSException *) davSetProperties: (NSDictionary *) setProps
+            removePropertiesNamed: (NSDictionary *) removedProps
+                        inContext: (WOContext *) localContext
+{
+  NSString *currentProp;
+  NSException *exception;
+  NSEnumerator *properties;
+  id currentValue;
+  SEL methodSel;
+
+  properties = [[setProps allKeys] objectEnumerator];
+  exception = nil;
+  while (!exception
+        && (currentProp = [properties nextObject]))
+    {
+      methodSel = NSSelectorFromString ([currentProp davSetterName]);
+      if ([self respondsToSelector: methodSel])
+       {
+         currentValue = [setProps objectForKey: currentProp];
+         exception = [self performSelector: methodSel
+                           withObject: currentValue];
+       }
+      else
+       exception
+         = [NSException exceptionWithHTTPStatus: 404
+                        reason: [NSString stringWithFormat:
+                                            @"Property '%@' cannot be set.",
+                                          currentProp]];
+    }
+
+  return exception;
+}
+
 @end /* SOGoObject */
index 03c067cea19dbe88ea4240c6697bb78d190f4ae8..54f53073dc19b1c5f803719cb49bc8781844e6e3 100644 (file)
@@ -36,6 +36,8 @@
 
 @class NSArray;
 @class NSDictionary;
+@class NSMutableArray;
+@class NSMutableDictionary;
 @class NSString;
 @class NSTimeZone;
 @class NSURL;
index 96b6cbc158647630a9f8c3f8dbf3035a4741a379..4d4a751eec1ea254d6610fbaf52da31c113b2124 100644 (file)
@@ -41,7 +41,6 @@
   NSString *owner;
   NSString *login;
   NSString *baseFolder;
-  NSString *subscriptionPointer;
   NSMutableDictionary *moduleSettings;
   BOOL isMailInvitation;
 }
index d8c65968537ccfc75044a9e1a2b132b54b0abcae..a2d6f64d19f97ebc72df436fad09d19554f50cc9 100644 (file)
@@ -50,8 +50,7 @@
 
 - (void) _setupContext
 {
-  NSString *folder, *mailInvitationParam;
-  NSArray *realFolderPath;
+  NSString *mailInvitationParam;
   SOGoUser *activeUser;
 
   activeUser = [context activeUser];
     }
   [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, folder];
-
   mailInvitationParam
     = [[context request] formValueForKey: @"mail-invitation"];
   isMailInvitation = [mailInvitationParam boolValue];
@@ -89,7 +79,7 @@
 {
   WOResponse *response;
   NSMutableArray *folderSubscription;
-  NSString *mailInvitationURL;
+  NSString *mailInvitationURL, *subscriptionPointer;
 
   if ([owner isEqualToString: login])
     {
          [moduleSettings setObject: folderSubscription
                          forKey: @"SubscribedFolders"];
        }
+      subscriptionPointer = [[self clientObject] folderReference];
       if (reallyDo)
        [folderSubscription addObjectUniquely: subscriptionPointer];
       else
index 16cf11bf6f8f70ab3186c7f175fab9e1ce05ac10..ba403b8d770ff5cdf4d19157f36d130334192962 100644 (file)
@@ -16,8 +16,6 @@
                     box_botleft.gif,
                     box_bottom.gif,
                     box_botright.gif,
-                    tab_selected.gif,
-                    tab_.gif,
                     corner_right.gif,
                     closewindow.gif,
                     OGoLogo.gif,
index 96dc6704f25b86a12256b07d78fcf3190734e553..ed855818d2ae2062848020cf2ed8305af8591169 100644 (file)
@@ -36,8 +36,7 @@
 
 - (void) dealloc
 {
-  if (refreshMethod)
-    [refreshMethod release];
+  [refreshMethod release];
   [super dealloc];
 }
 
 
 - (void) setRefreshMethod: (NSString *) method
 {
-  if (refreshMethod)
-    [refreshMethod release];
-  refreshMethod = method;
-  if (refreshMethod)
-    [refreshMethod retain];
+  ASSIGN (refreshMethod, method);
 }
 
 - (NSString *) refreshMethod
index beed29420520f69fd0284ab5e2febb57c4b56ba1..005b36d4aea83b45639fef21eec3f0f0b3f39393 100644 (file)
@@ -13,6 +13,8 @@ SchedulerUI_OBJC_FILES =              \
        NSArray+Scheduler.m             \
                                        \
        UIxCalMainView.m                \
+       UIxCalendarProperties.m         \
+       UIxColorPicker.m                \
                                        \
        UIxCalFilterPanel.m             \
        UIxCalDayTable.m                \
diff --git a/UI/Scheduler/UIxCalendarProperties.h b/UI/Scheduler/UIxCalendarProperties.h
new file mode 100644 (file)
index 0000000..e8ebc8c
--- /dev/null
@@ -0,0 +1,42 @@
+/* UIxCalendarProperties.m - this file is part of SOGo
+ *
+ * Copyright (C) 2008 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 "SOGoUI/UIxComponent.h"
+
+@class NSString;
+
+@class SOGoAppointmentFolder;
+
+@interface UIxCalendarProperties : UIxComponent
+{
+  SOGoAppointmentFolder *calendar;
+}
+
+- (NSString *) calendarName;
+- (void) setCalendarName: (NSString *) newName;
+- (NSString *) calendarNameIsDisabled;
+
+- (NSString *) calendarColor;
+- (void) setCalendarColor: (NSString *) newColor;
+
+
+@end
diff --git a/UI/Scheduler/UIxCalendarProperties.m b/UI/Scheduler/UIxCalendarProperties.m
new file mode 100644 (file)
index 0000000..0dbb77c
--- /dev/null
@@ -0,0 +1,91 @@
+/* UIxCalendarProperties.m - this file is part of SOGo
+ *
+ * Copyright (C) 2008 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 <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+
+#import "UIxCalendarProperties.h"
+
+@implementation UIxCalendarProperties
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      calendar = [self clientObject];
+    }
+
+  return self;
+}
+
+- (NSString *) calendarID
+{
+  return [calendar folderReference];
+}
+
+- (NSString *) calendarName
+{
+  return [calendar displayName];
+}
+
+- (void) setCalendarName: (NSString *) newName
+{
+  NSString *login;
+
+  login = [[context activeUser] login];
+
+  if ([login isEqualToString: [calendar ownerInContext: context]])
+    [calendar renameTo: newName];
+}
+
+- (NSString *) calendarNameIsDisabled
+{
+  NSString *login;
+
+  login = [[context activeUser] login];
+
+  return ([login isEqualToString: [calendar ownerInContext: context]]
+         ? @"false" : @"true");
+}
+
+- (NSString *) calendarColor
+{
+  return [calendar calendarColor];
+}
+
+- (void) setCalendarColor: (NSString *) newColor
+{
+  [calendar setCalendarColor: newColor];
+}
+
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
+                           inContext: (WOContext*) context
+{
+  return YES;
+}
+
+- (id <WOActionResults>) savePropertiesAction
+{
+  return [self jsCloseWithRefreshMethod: nil];
+}
+
+@end
index 743375ee7d6952ed8194e21ee0e9c3f66ebaaefe..820865478e469f996aff5dc720c7f8fa0f122176 100644 (file)
 
 #import "UIxCalendarSelector.h"
 
-// static inline char
-// darkenedColor (const char value)
-// {
-//   char newValue;
-
-//   if (value >= '0' && value <= '9')
-//     newValue = ((value - '0') / 2) + '0';
-//   else if (value >= 'a' && value <= 'f')
-//     newValue = ((value + 10 - 'a') / 2) + '0';
-//   else if (value >= 'A' && value <= 'F')
-//     newValue = ((value + 10 - 'A') / 2) + '0';
-//   else
-//     newValue = value;
-
-//   return newValue;
-// }
-
-static inline NSString *
-colorForNumber (unsigned int number)
-{
-  unsigned int index, currentValue;
-  unsigned char colorTable[] = { 1, 1, 1 };
-  NSString *color;
-
-  if (number == 0)
-    color = @"#ccf";
-  else if (number == NSNotFound)
-    color = @"#f00";
-  else
-    {
-      currentValue = number;
-      index = 0;
-      while (currentValue)
-        {
-          if (currentValue & 1)
-            colorTable[index]++;
-          if (index == 3)
-            index = 0;
-          currentValue >>= 1;
-          index++;
-        }
-      color = [NSString stringWithFormat: @"#%2x%2x%2x",
-                        (255 / colorTable[2]) - 1,
-                        (255 / colorTable[1]) - 1,
-                        (255 / colorTable[0]) - 1];
-    }
-
-  return color;
-}
-
 @implementation UIxCalendarSelector
 
 - (id) init
@@ -137,7 +87,7 @@ colorForNumber (unsigned int number)
                    forKey: @"id"];
          [calendar setObject: fDisplayName forKey: @"displayName"];
          [calendar setObject: folderName forKey: @"folder"];
-         [calendar setObject: colorForNumber (count)
+         [calendar setObject: [folder calendarColor]
                    forKey: @"color"];
          isActive = [NSNumber numberWithBool: [folder isActive]];
          [calendar setObject: isActive forKey: @"active"];
diff --git a/UI/Scheduler/UIxColorPicker.h b/UI/Scheduler/UIxColorPicker.h
new file mode 100644 (file)
index 0000000..9a12eff
--- /dev/null
@@ -0,0 +1,31 @@
+/* UIxColorPicker.h - this file is part of SOGo
+ *
+ * Copyright (C) 2008 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 UIXCOLORPICKER_H
+#define UIXCOLORPICKER_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@interface UIxColorPicker : UIxComponent
+@end
+
+#endif /* UIXCOLORPICKER_H */
diff --git a/UI/Scheduler/UIxColorPicker.m b/UI/Scheduler/UIxColorPicker.m
new file mode 100644 (file)
index 0000000..d468061
--- /dev/null
@@ -0,0 +1,29 @@
+/* UIxColorPicker.m - this file is part of SOGo
+ *
+ * Copyright (C) 2008 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 "UIxColorPicker.h"
+
+#warning this module should probably be moved into a "Utility" product
+
+@implementation UIxColorPicker
+
+@end
index 85db92f0009e6977f355c628d002a646bdc2df9d..b18b596bd902ff416e87af1db15381590f919778 100644 (file)
              protectedBy = "View";
              pageName    = "UIxRecurrenceEditor";
           };
+          colorPicker = {
+            protectedBy = "View";
+            pageName = "UIxColorPicker";
+          };
        };
      };
 
      SOGoAppointmentFolder = {
        methods = {
-          newevent = {
-             protectedBy = "Add Documents, Images, and Files";
-             pageName    = "UIxAppointmentEditor"; 
-             actionName  = "new";
+          properties = { 
+             protectedBy = "Access Contents Information";
+             pageName    = "UIxCalendarProperties"; 
           };
-          newtask = { 
-             protectedBy = "Add Documents, Images, and Files";
-             pageName    = "UIxTaskEditor"; 
-             actionName  = "new";
+          saveProperties = { 
+             protectedBy = "Access Contents Information";
+             pageName = "UIxCalendarProperties";
+             actionName = "saveProperties";
           };
           show = { 
              protectedBy = "View";
              pageName    = "UIxCalUserRightsEditor";
              actionName  = "saveUserRights";
           };
+          newevent = {
+             protectedBy = "Add Documents, Images, and Files";
+             pageName    = "UIxAppointmentEditor"; 
+             actionName  = "new";
+          };
+          newtask = { 
+             protectedBy = "Add Documents, Images, and Files";
+             pageName    = "UIxTaskEditor"; 
+             actionName  = "new";
+          };
        };
      };
 
diff --git a/UI/Templates/SchedulerUI/UIxCalendarProperties.wox b/UI/Templates/SchedulerUI/UIxCalendarProperties.wox
new file mode 100644 (file)
index 0000000..5207d7f
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:var="http://www.skyrix.com/od/binding"
+  xmlns:const="http://www.skyrix.com/od/constant"
+  xmlns:uix="OGo:uix"
+  xmlns:rsrc="OGo:url"
+  xmlns:label="OGo:label"
+  className="UIxPageFrame"
+  const:toolbar="none"
+  const:popup="YES"
+  title="title">
+  <form const:href="saveProperties" name="propertiesform">
+    <input type="hidden" const:name="calendarID" const:id="calendarID" var:value="calendarID"/>
+    <div id="propertiesView">
+      <label><var:string label:value="Name:" /><span class="content"
+          ><input type="text" name="calendarName" id="calendarName"
+           var:disabled="calendarNameIsDisabled"
+            class="textField"
+            var:value="calendarName"
+            /></span></label>
+      <label><var:string label:value="Color:" /><span class="content"
+          ><button id="colorButton"><!-- space --></button>
+         <input type="hidden"
+           name="calendarColor"
+           id="calendarColor"
+            class="textField"
+            var:value="calendarColor"
+            /></span></label>
+    </div>
+    <div id="buttons">
+      <input type="button"
+       const:class="button"
+       label:value="Cancel"
+       const:id="cancelButton"
+       name="cancelButton"/>
+      <input type="submit"
+       const:class="button"
+       label:value="OK"
+       const:id="okButton"
+       name="okButton"/>
+    </div>
+  </form>
+</var:component>
diff --git a/UI/Templates/SchedulerUI/UIxColorPicker.wox b/UI/Templates/SchedulerUI/UIxColorPicker.wox
new file mode 100644 (file)
index 0000000..6687b7c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:var="http://www.skyrix.com/od/binding"
+  xmlns:const="http://www.skyrix.com/od/constant"
+  xmlns:uix="OGo:uix"
+  xmlns:rsrc="OGo:url"
+  xmlns:label="OGo:label"
+  className="UIxPageFrame"
+  const:toolbar="none"
+  const:popup="YES"
+  title="title"
+  const:jsFiles="js_color_picker_v2.js"
+  const:cssFiles="js_color_picker_v2.css">
+  <input type="hidden" const:name="pickerValue" const:id="pickerValue"/>
+</var:component>
index 06275838b35d8cdf72e85cf962f4bacbb1cc1d55..bb209932a087400e19ab0a205b39faa4c10a2cea 100644 (file)
@@ -7,7 +7,7 @@
         ><script type="text/javascript"
           ><var:if condition="hasRefreshMethod"
             >window.opener.setTimeout('<var:string value="refreshMethod"
-              const:escapeHTML="NO" />;', 200);</var:if
+              const:escapeHTML="NO" />;', 50);</var:if
             >window.close();</script
 ></body></html
 ></container>
index 714dd0df7d775af35b279af1ea98ca1694a83f1b..903ac7e857e4e8817f5902f492165fc3039fba45 100644 (file)
@@ -1617,30 +1617,25 @@ function initCalendarSelector() {
 function onCalendarModify(event) {
   var folders = $("calendarList");
   var selected = folders.getSelectedNodes()[0];
-
-  if (UserLogin == selected.getAttribute("owner")) {
-    var node = selected.childNodes[selected.childNodes.length - 1];
-    var currentName = node.nodeValue.trim();
-    var newName = window.prompt(labels["Name of the Calendar"],
-                               currentName);
-    if (newName && newName.length > 0
-       && newName != currentName) {
-      var url = (URLForFolderID(selected.getAttribute("id"))
-                + "/renameFolder?name=" + escape(newName.utf8encode()));
-      triggerAjaxRequest(url, folderRenameCallback,
-                        {node: node, name: " " + newName});
-    }
-  } else
-    window.alert(clabels["Unable to rename that folder!"]);
+  var calendarID = selected.getAttribute("id");
+  var url = ApplicationBaseURL + calendarID + "/properties";
+  var properties = window.open(url, calendarID + "properties",
+                              "width=300,height=100,resizable=0,scrollbars=0"
+                              + "toolbar=0,location=0,directories=0,status=0,"
+                              + "menubar=0,copyhistory=0");
+  properties.focus();
 }
 
-function folderRenameCallback(http) {
-  if (http.readyState == 4) {
-    if (isHttpStatus204(http.status)) {
-      var dict = http.callbackData;
-      dict["node"].nodeValue = dict["name"];
-    }
-  }
+function updateCalendarProperties(calendarID, calendarName, calendarColor) {
+  var idParts = calendarID.split(":");
+  var nodeID = "/" + idParts[0];
+  if (idParts.length > 1)
+    nodeID += "_" + idParts[1].split("/")[1];
+  var calendarNode = $(nodeID);
+  var childNodes = calendarNode.childNodes;
+  childNodes[childNodes.length-1].nodeValue = calendarName;
+
+  appendStyleElement(nodeID, calendarColor);
 }
 
 function onCalendarNew(event) {
@@ -1743,8 +1738,12 @@ function appendCalendar(folderName, folderPath) {
     triggerAjaxRequest(url, calendarEntryCallback, folderPath);
     
     // Update CSS for events color
-    if (!document.styleSheets) return;
-    
+    appendStyleElement(folderPath, color);
+  }
+}
+
+function appendStyleElement(folderPath, color) {
+  if (document.styleSheets) {    
     var styleElement = document.createElement("style");
     styleElement.type = "text/css";
     var selectors = [
diff --git a/UI/WebServerResources/UIxCalendarProperties.css b/UI/WebServerResources/UIxCalendarProperties.css
new file mode 100644 (file)
index 0000000..dc80db0
--- /dev/null
@@ -0,0 +1,36 @@
+LABEL
+{ display: block;
+  position: relative;
+  line-height: 1.5em;
+  height: 1.5em;
+  margin-left: .5em;
+  margin-bottom: .5em;
+  width: 100%; }
+
+DIV#propertiesView
+{ overflow: hidden;
+  padding: .5em; }
+
+SPAN.content
+{ position: absolute;
+  top: -.25em;
+  left: 8em;
+  right: 1em; }
+
+BUTTON#colorButton
+{
+  display: none;
+  margin: 1px;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  -moz-border-top-colors: #9c9a94 #000 transparent;
+  -moz-border-left-colors: #9c9a94 #000 transparent;
+  width: 3em;
+  height: 2em;
+}
+
+DIV#buttons
+{ padding: .5em;
+  text-align: right; }
diff --git a/UI/WebServerResources/UIxCalendarProperties.js b/UI/WebServerResources/UIxCalendarProperties.js
new file mode 100644 (file)
index 0000000..340d33a
--- /dev/null
@@ -0,0 +1,46 @@
+function onLoadCalendarProperties() {
+  var colorButton = $("colorButton");
+  var calendarColor = $("calendarColor");
+  colorButton.setStyle({ "backgroundColor": calendarColor.value, display: "inline" });
+  colorButton.observe("click", onColorClick);
+
+  var cancelButton = $("cancelButton");
+  cancelButton.observe("click", onCancelClick);
+
+  var okButton = $("okButton");
+  okButton.observe("click", onOKClick);
+}
+
+function onCancelClick(event) {
+  window.close();
+}
+
+function onOKClick(event) {
+  var calendarName = $("calendarName");
+  var calendarColor = $("calendarColor");
+  var calendarID = $("calendarID");
+
+  window.opener.updateCalendarProperties(calendarID.value,
+                                        calendarName.value,
+                                        calendarColor.value);
+}
+
+function onColorClick(event) {
+  var cPicker = window.open(ApplicationBaseURL + "colorPicker", "colorPicker",
+                           "width=250,height=200,resizable=0,scrollbars=0"
+                           + "toolbar=0,location=0,directories=0,status=0,"
+                           + "menubar=0,copyhistory=0", "test"
+                           );
+  cPicker.focus();
+
+  preventDefault(event);
+}
+
+function onColorPickerChoice(newColor) {
+  var colorButton = $("colorButton");
+  colorButton.setStyle({ "backgroundColor": newColor });
+  var calendarColor = $("calendarColor");
+  calendarColor.value = newColor;
+}
+
+FastInit.addOnLoad(onLoadCalendarProperties);
diff --git a/UI/WebServerResources/UIxColorPicker.js b/UI/WebServerResources/UIxColorPicker.js
new file mode 100644 (file)
index 0000000..892635d
--- /dev/null
@@ -0,0 +1,9 @@
+function onLoadColorPicker(event) {
+  showColorPicker();
+}
+
+function onChooseColor(newColor) {
+  window.opener.onColorPickerChoice(newColor);
+}
+
+FastInit.addOnLoad(onLoadColorPicker);
diff --git a/UI/WebServerResources/js_color_picker_v2.css b/UI/WebServerResources/js_color_picker_v2.css
new file mode 100644 (file)
index 0000000..f85fb4a
--- /dev/null
@@ -0,0 +1,191 @@
+       #dhtmlgoodies_colorPicker{
+               position:absolute;
+               width:250px;
+               padding-bottom:1px;
+               background-color:#FFF;
+               border:1px solid #317082;
+               
+               width: 252px;   /* IE 5.x */
+               width/* */:/**/250px;   /* Other browsers */
+               width: /**/250px;       
+                               
+       }
+       
+       #dhtmlgoodies_colorPicker .colorPicker_topRow{
+               padding-bottom:1px;
+               border-bottom:3px double #317082;
+               background-color:#E2EBED;
+               padding-left:2px;
+               
+               width: 250px;   /* IE 5.x */
+               width/* */:/**/248px;   /* Other browsers */
+               width: /**/248px;       
+               
+               height: 20px;   /* IE 5.x */
+               height/* */:/**/16px;   /* Other browsers */
+               height: /**/16px;       
+                               
+       }
+       
+       #dhtmlgoodies_colorPicker .colorPicker_statusBar{
+               height:13px;
+               padding-bottom:2px;
+               width:248px;
+               border-top:3px double #317082;  
+               background-color:#E2EBED;
+               padding-left:2px;
+               clear:both;
+               
+               width: 250px;   /* IE 5.x */
+               width/* */:/**/248px;   /* Other browsers */
+               width: /**/248px;       
+               
+               height: 18px;   /* IE 5.x */
+               height/* */:/**/13px;   /* Other browsers */
+               height: /**/13px;       
+                                               
+       }
+       
+       #dhtmlgoodies_colorPicker .colorSquare{
+               margin-left:1px;
+               margin-bottom:1px;
+               float:left;
+               border:1px solid #000;
+               cursor:pointer;
+               
+               width: 12px;    /* IE 5.x */
+               width/* */:/**/10px;    /* Other browsers */
+               width: /**/10px;        
+               
+               height: 12px;   /* IE 5.x */
+               height/* */:/**/10px;   /* Other browsers */
+               height: /**/10px;       
+                               
+       }
+       
+       .colorPickerTab_inactive,.colorPickerTab_active{
+       
+               height:17px;
+               padding-left:4px;
+               cursor:pointer; 
+               
+               
+       }
+       .colorPickerTab_inactive span{
+               background-image:url('tab_left_inactive.gif');
+       }
+       
+       .colorPickerTab_active span{
+               background-image:url('tab_left_active.gif');
+
+       }
+       .colorPickerTab_inactive span, .colorPickerTab_active span{
+               line-height:16px;
+               font-weight:bold;
+               font-family:arial;
+               font-size:11px;
+               padding-top:1px;
+               vertical-align:middle;
+               background-position:top left;
+               background-repeat: no-repeat;   
+               float:left;
+               padding-left:6px;
+               -moz-user-select:no;
+       }       
+       .colorPickerTab_inactive img,.colorPickerTab_active img{
+               float:left;
+       }
+       .colorPickerCloseButton{
+               width:11px;
+               height:11px;
+               text-align:center;
+               line-height:10px;
+               border:1px solid #317082;
+               position:absolute;
+               right:1px;
+               font-size:12px;
+               font-weight:bold;
+               top:1px;
+               padding:1px;
+               cursor:pointer; 
+               
+               width: 15px;    /* IE 5.x */
+               width/* */:/**/11px;    /* Other browsers */
+               width: /**/11px;
+               
+               height: 15px;   /* IE 5.x */
+               height/* */:/**/11px;   /* Other browsers */
+               height: /**/11px;
+
+                       
+       }
+       #colorPicker_statusBarTxt{
+               font-size:11px;
+               font-family:arial;
+               vertical-align:top;
+               line-height:13px;
+
+       }
+       form{
+               padding-left:5px;
+       }
+       
+       .form_widget_amount_slider{
+               border-top:1px solid #9d9c99;
+               border-left:1px solid #9d9c99;
+               border-bottom:1px solid #eee;
+               border-right:1px solid #eee;
+               background-color:#f0ede0;
+               position:absolute;
+               bottom:0px;
+               
+               width: 5px;     /* IE 5.x */
+               width/* */:/**/3px;     /* Other browsers */
+               width: /**/3px;
+               
+               height: 5px;    /* IE 5.x */
+               height/* */:/**/3px;    /* Other browsers */
+               height: /**/3px;
+                               
+       }
+       .colorSliderLabel{
+               width:15px;
+               height:20px;
+               float:left;
+               font-size:11px;
+               font-weight:bold;
+       }
+       .colorSlider{
+               width:175px;
+               height:20px;
+               float:left;
+       }
+       .colorInput{
+               width:45px;
+               height:20px;
+               float:left;
+       }       
+       .colorPreviewDiv{
+               width:186px;
+               margin-right:2px;
+               margin-top:1px;
+               border:1px solid #CCC;
+               height:20px;
+               float:left;
+               cursor:pointer;
+               
+               width: 188px;   /* IE 5.x */
+               width/* */:/**/186px;   /* Other browsers */
+               width: /**/186px;
+               
+               height: 22px;   /* IE 5.x */
+               height/* */:/**/20px;   /* Other browsers */
+               height: /**/20px;
+                               
+
+       }
+       .colorCodeDiv{
+               width:50px;
+               height:20px;
+               float:left;
+       }
\ No newline at end of file
diff --git a/UI/WebServerResources/js_color_picker_v2.js b/UI/WebServerResources/js_color_picker_v2.js
new file mode 100644 (file)
index 0000000..9c9a9b6
--- /dev/null
@@ -0,0 +1,580 @@
+/************************************************************************************************************
+@fileoverview
+JS Color picker
+Copyright (C) October 2005,  DHTMLGoodies.com, Alf Magne Kalleland
+
+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 2.1 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
+Lesser 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  02110-1301  USA
+
+Dhtmlgoodies.com., hereby disclaims all copyright interest in this script
+written by Alf Magne Kalleland.
+
+Alf Magne Kalleland, 2007
+Owner of DHTMLgoodies.com
+
+
+************************************************************************************************************/  
+
+var MSIE = navigator.userAgent.indexOf('MSIE')>=0?true:false;
+var navigatorVersion = navigator.appVersion.replace(/.*?MSIE (\d\.\d).*/g,'$1')/1;
+       
+var form_widget_amount_slider_handle = ResourcesURL + "/slider_handle.gif";
+var slider_handle_image_obj = false;
+var sliderObjectArray = new Array();
+var slider_counter = 0;
+var slideInProgress = false;
+var handle_start_x;
+var event_start_x;
+var currentSliderIndex;
+       
+function form_widget_cancel_event()
+{
+  return false;                
+}
+       
+function getImageSliderHeight(){
+  if(!slider_handle_image_obj){
+    slider_handle_image_obj = new Image();
+    slider_handle_image_obj.src = form_widget_amount_slider_handle;
+  }
+  if(slider_handle_image_obj.width>0){
+    return;
+  }else{
+    setTimeout('getImageSliderHeight()',50);
+  }
+}
+       
+function positionSliderImage(e,theIndex,inputObj)
+{
+  if(this)inputObj = this;
+  if(!theIndex)theIndex = inputObj.getAttribute('sliderIndex');
+  var handleImg = document.getElementById('slider_handle' + theIndex);
+  var ratio = sliderObjectArray[theIndex]['width'] / (sliderObjectArray[theIndex]['max']-sliderObjectArray[theIndex]['min']);
+  var currentValue = sliderObjectArray[theIndex]['formTarget'].value-sliderObjectArray[theIndex]['min'];               
+  handleImg.style.left = currentValue * ratio + 'px';                  
+  setColorByRGB();
+}
+       
+function adjustFormValue(theIndex)
+{
+  var handleImg = document.getElementById('slider_handle' + theIndex); 
+  var ratio = sliderObjectArray[theIndex]['width'] / (sliderObjectArray[theIndex]['max']-sliderObjectArray[theIndex]['min']);
+  var currentPos = handleImg.style.left.replace('px','');
+  sliderObjectArray[theIndex]['formTarget'].value = Math.round(currentPos / ratio) + sliderObjectArray[theIndex]['min'];
+               
+}
+               
+function initMoveSlider(e)
+{
+       
+  if(document.all)e = event;   
+  slideInProgress = true;
+  event_start_x = e.clientX;
+  handle_start_x = this.style.left.replace('px','');
+  currentSliderIndex = this.id.replace(/[^\d]/g,'');
+  return false;
+}
+       
+function startMoveSlider(e)
+{
+  if(document.all)e = event;   
+  if(!slideInProgress)return;  
+  var leftPos = handle_start_x/1 + e.clientX/1 - event_start_x;
+  if(leftPos<0)leftPos = 0;
+  if(leftPos/1>sliderObjectArray[currentSliderIndex]['width'])leftPos = sliderObjectArray[currentSliderIndex]['width'];
+  document.getElementById('slider_handle' + currentSliderIndex).style.left = leftPos + 'px';
+  adjustFormValue(currentSliderIndex);
+  if(sliderObjectArray[currentSliderIndex]['onchangeAction']){
+    eval(sliderObjectArray[currentSliderIndex]['onchangeAction']);
+  }
+}
+       
+function stopMoveSlider()
+{
+  slideInProgress = false;
+}
+       
+       
+function form_widget_amount_slider(targetElId,formTarget,width,min,max,onchangeAction)
+{
+  if(!slider_handle_image_obj){
+    getImageSliderHeight();            
+  }
+                               
+  slider_counter = slider_counter +1;
+  sliderObjectArray[slider_counter] = new Array();
+  sliderObjectArray[slider_counter] = {"width":width - 9,"min":min,"max":max,"formTarget":formTarget,"onchangeAction":onchangeAction};
+               
+  formTarget.setAttribute('sliderIndex',slider_counter);
+  formTarget.onchange = positionSliderImage;
+  var parentObj = document.createElement('DIV');
+  parentObj.style.width = width + 'px';
+  parentObj.style.height = '12px';     // The height of the image
+  parentObj.style.position = 'relative';
+  parentObj.id = 'slider_container' + slider_counter;
+  document.getElementById(targetElId).appendChild(parentObj);
+               
+  var obj = document.createElement('DIV');
+  obj.className = 'form_widget_amount_slider';
+  obj.innerHTML = '<span></span>';
+  obj.style.width = width + 'px';
+  obj.id = 'slider_slider' + slider_counter;
+  obj.style.position = 'absolute';
+  obj.style.bottom = '0px';
+  parentObj.appendChild(obj);
+               
+  var handleImg = document.createElement('IMG');
+  handleImg.style.position = 'absolute';
+  handleImg.style.left = '0px';
+  handleImg.style.zIndex = 5;
+  handleImg.src = slider_handle_image_obj.src;
+  handleImg.id = 'slider_handle' + slider_counter;
+  handleImg.onmousedown = initMoveSlider;
+  if(document.body.onmouseup){
+    if(document.body.onmouseup.toString().indexOf('stopMoveSlider')==-1){
+      alert('You allready have an onmouseup event assigned to the body tag');
+    }
+  }else{
+    document.body.onmouseup = stopMoveSlider;  
+    document.body.onmousemove = startMoveSlider;       
+  }
+  handleImg.ondragstart = form_widget_cancel_event;
+  parentObj.appendChild(handleImg);
+  positionSliderImage(false,slider_counter);
+}
+               
+
+       
+var namedColors = new Array('AliceBlue','AntiqueWhite','Aqua','Aquamarine','Azure','Beige','Bisque','Black','BlanchedAlmond','Blue','BlueViolet','Brown',
+                           'BurlyWood','CadetBlue','Chartreuse','Chocolate','Coral','CornflowerBlue','Cornsilk','Crimson','Cyan','DarkBlue','DarkCyan','DarkGoldenRod','DarkGray',
+                           'DarkGreen','DarkKhaki','DarkMagenta','DarkOliveGreen','Darkorange','DarkOrchid','DarkRed','DarkSalmon','DarkSeaGreen','DarkSlateBlue','DarkSlateGray',
+                           'DarkTurquoise','DarkViolet','DeepPink','DeepSkyBlue','DimGray','DodgerBlue','Feldspar','FireBrick','FloralWhite','ForestGreen','Fuchsia','Gainsboro',
+                           'GhostWhite','Gold','GoldenRod','Gray','Green','GreenYellow','HoneyDew','HotPink','IndianRed','Indigo','Ivory','Khaki','Lavender','LavenderBlush',
+                           'LawnGreen','LemonChiffon','LightBlue','LightCoral','LightCyan','LightGoldenRodYellow','LightGrey','LightGreen','LightPink','LightSalmon','LightSeaGreen',
+                           'LightSkyBlue','LightSlateBlue','LightSlateGray','LightSteelBlue','LightYellow','Lime','LimeGreen','Linen','Magenta','Maroon','MediumAquaMarine',
+                           'MediumBlue','MediumOrchid','MediumPurple','MediumSeaGreen','MediumSlateBlue','MediumSpringGreen','MediumTurquoise','MediumVioletRed','MidnightBlue',
+                           'MintCream','MistyRose','Moccasin','NavajoWhite','Navy','OldLace','Olive','OliveDrab','Orange','OrangeRed','Orchid','PaleGoldenRod','PaleGreen',
+                           'PaleTurquoise','PaleVioletRed','PapayaWhip','PeachPuff','Peru','Pink','Plum','PowderBlue','Purple','Red','RosyBrown','RoyalBlue','SaddleBrown',
+                           'Salmon','SandyBrown','SeaGreen','SeaShell','Sienna','Silver','SkyBlue','SlateBlue','SlateGray','Snow','SpringGreen','SteelBlue','Tan','Teal','Thistle',
+                           'Tomato','Turquoise','Violet','VioletRed','Wheat','White','WhiteSmoke','Yellow','YellowGreen');
+       
+var namedColorRGB = new Array('#F0F8FF','#FAEBD7','#00FFFF','#7FFFD4','#F0FFFF','#F5F5DC','#FFE4C4','#000000','#FFEBCD','#0000FF','#8A2BE2','#A52A2A','#DEB887',
+                             '#5F9EA0','#7FFF00','#D2691E','#FF7F50','#6495ED','#FFF8DC','#DC143C','#00FFFF','#00008B','#008B8B','#B8860B','#A9A9A9','#006400','#BDB76B','#8B008B',
+                             '#556B2F','#FF8C00','#9932CC','#8B0000','#E9967A','#8FBC8F','#483D8B','#2F4F4F','#00CED1','#9400D3','#FF1493','#00BFFF','#696969','#1E90FF','#D19275',
+                             '#B22222','#FFFAF0','#228B22','#FF00FF','#DCDCDC','#F8F8FF','#FFD700','#DAA520','#808080','#008000','#ADFF2F','#F0FFF0','#FF69B4','#CD5C5C','#4B0082',
+                             '#FFFFF0','#F0E68C','#E6E6FA','#FFF0F5','#7CFC00','#FFFACD','#ADD8E6','#F08080','#E0FFFF','#FAFAD2','#D3D3D3','#90EE90','#FFB6C1','#FFA07A','#20B2AA',
+                             '#87CEFA','#8470FF','#778899','#B0C4DE','#FFFFE0','#00FF00','#32CD32','#FAF0E6','#FF00FF','#800000','#66CDAA','#0000CD','#BA55D3','#9370D8','#3CB371',
+                             '#7B68EE','#00FA9A','#48D1CC','#C71585','#191970','#F5FFFA','#FFE4E1','#FFE4B5','#FFDEAD','#000080','#FDF5E6','#808000','#6B8E23','#FFA500','#FF4500',
+                             '#DA70D6','#EEE8AA','#98FB98','#AFEEEE','#D87093','#FFEFD5','#FFDAB9','#CD853F','#FFC0CB','#DDA0DD','#B0E0E6','#800080','#FF0000','#BC8F8F','#4169E1',
+                             '#8B4513','#FA8072','#F4A460','#2E8B57','#FFF5EE','#A0522D','#C0C0C0','#87CEEB','#6A5ACD','#708090','#FFFAFA','#00FF7F','#4682B4','#D2B48C','#008080',
+                             '#D8BFD8','#FF6347','#40E0D0','#EE82EE','#D02090','#F5DEB3','#FFFFFF','#F5F5F5','#FFFF00','#9ACD32');     
+       
+       
+var color_picker_div = false;
+var color_picker_active_tab = false;
+//     var color_picker_form_field = false;
+//     var color_picker_active_input = false;
+function baseConverter (number,ob,nb) {
+  number = number + "";
+  number = number.toUpperCase();
+  var list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  var dec = 0;
+  for (var i = 0; i <=  number.length; i++) {
+    dec += (list.indexOf(number.charAt(i))) * (Math.pow(ob , (number.length - i - 1)));
+  }
+  number = "";
+  var magnitude = Math.floor((Math.log(dec))/(Math.log(nb)));
+  for (var i = magnitude; i >= 0; i--) {
+    var amount = Math.floor(dec/Math.pow(nb,i));
+    number = number + list.charAt(amount); 
+    dec -= amount*(Math.pow(nb,i));
+  }
+  if(number.length==0)number=0;
+  return number;
+}
+       
+//     function colorPickerGetTopPos(inputObj)
+//     {
+               
+//       var returnValue = inputObj.offsetTop;
+//       while((inputObj = inputObj.offsetParent) != null){
+//             returnValue += inputObj.offsetTop;
+//       }
+//       return returnValue;
+//     }
+       
+//     function colorPickerGetLeftPos(inputObj)
+//     {
+//       var returnValue = inputObj.offsetLeft;
+//       while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
+//       return returnValue;
+//     }
+       
+function cancelColorPickerEvent(){
+  return false;
+}
+       
+function showHideColorOptions(e,inputObj)
+{
+  var thisObj = this;
+  if(inputObj){
+    var parentNode = inputObj.parentNode; 
+    thisObj = inputObj;
+  }else var parentNode = this.parentNode;
+  var activeColorDiv = false;
+  var subDiv = parentNode.getElementsByTagName('DIV')[0];
+  counter=0;   
+  var initZIndex = 10; 
+  var contentDiv = document.getElementById('color_picker_content').getElementsByTagName('DIV')[0];
+  do{                  
+    if(subDiv.tagName=='DIV') {
+      if(subDiv==thisObj){
+       thisObj.className='colorPickerTab_active';
+       thisObj.style.zIndex = 50;
+       var img = thisObj.getElementsByTagName('IMG')[0];
+       img.src = ResourcesURL + "/tab_right_active.gif"
+         img.src = img.src.replace(/inactive/,'active');                                                       
+       contentDiv.style.display='block';
+       activeColorDiv = contentDiv;
+      }else{
+       subDiv.className = 'colorPickerTab_inactive';   
+       var img = subDiv.getElementsByTagName('IMG')[0];
+       img.src = ResourcesURL + "/tab_right_inactive.gif";
+       if(activeColorDiv)
+         subDiv.style.zIndex = initZIndex - counter;
+       else
+         subDiv.style.zIndex = counter;
+       contentDiv.style.display='none';
+      }
+      counter++;
+    }
+    subDiv = subDiv.nextSibling;
+    if(contentDiv.nextSibling)contentDiv = contentDiv.nextSibling;
+  }while(subDiv);
+               
+               
+  document.getElementById('colorPicker_statusBarTxt').innerHTML = '&nbsp;';
+
+
+}
+       
+function createColorPickerTopRow(inputObj){
+  var tabs = ['RGB','Named colors','Color slider'];
+  var tabWidths = [37,90,70];
+  var div = document.createElement('DIV');
+  div.className='colorPicker_topRow';
+       
+  inputObj.appendChild(div);   
+  var currentWidth = 0;
+  for(var no=0;no<tabs.length;no++){                   
+                       
+    var tabDiv = document.createElement('DIV');
+    tabDiv.onselectstart = cancelColorPickerEvent;
+    tabDiv.ondragstart = cancelColorPickerEvent;
+    if(no==0){
+      suffix = 'active'; 
+      color_picker_active_tab = this;
+    }else suffix = 'inactive';
+                       
+    tabDiv.id = 'colorPickerTab' + no;
+    tabDiv.onclick = showHideColorOptions;
+    if(no==0)tabDiv.style.zIndex = 50; else tabDiv.style.zIndex = 1 + (tabs.length-no);
+    tabDiv.style.left = currentWidth + 'px';
+    tabDiv.style.position = 'absolute';
+    tabDiv.className='colorPickerTab_' + suffix;
+    var tabSpan = document.createElement('SPAN');
+    tabSpan.innerHTML = tabs[no];
+    tabDiv.appendChild(tabSpan);
+    var tabImg = document.createElement('IMG');
+    tabImg.src = ResourcesURL + "/tab_right_" + suffix + ".gif";
+    tabDiv.appendChild(tabImg);
+    div.appendChild(tabDiv);
+    if(navigatorVersion<6 && MSIE){    /* Lower IE version fix */
+      tabSpan.style.position = 'relative';
+      tabImg.style.position = 'relative';
+      tabImg.style.left = '-3px';              
+      tabDiv.style.cursor = 'hand';    
+    }                  
+    currentWidth = currentWidth + tabWidths[no];
+               
+  }
+               
+  /*           var closeButton = document.createElement('DIV');
+               closeButton.className='colorPickerCloseButton';
+               closeButton.innerHTML = 'x';
+               closeButton.onclick = closeColorPicker;
+               closeButton.onmouseover = toggleCloseButton;
+               closeButton.onmouseout = toggleOffCloseButton;
+               div.appendChild(closeButton); */
+               
+}
+       
+function createWebColors(inputObj){
+  var webColorDiv = document.createElement('DIV');
+  webColorDiv.style.paddingTop = '1px';
+  inputObj.appendChild(webColorDiv);
+  for(var r=15;r>=0;r-=3){
+    for(var g=0;g<=15;g+=3){
+      for(var b=0;b<=15;b+=3){
+       var red = baseConverter(r,10,16) + '';
+       var green = baseConverter(g,10,16) + '';
+       var blue = baseConverter(b,10,16) + '';
+                                       
+       var color = '#' + red + red + green + green + blue + blue;
+       var div = document.createElement('DIV');
+       div.style.backgroundColor=color;
+       div.innerHTML = '<span></span>';
+       div.className='colorSquare';
+       div.title = color;      
+       div.onclick = chooseColor;
+       div.setAttribute('rgbColor',color);
+       div.onmouseover = colorPickerShowStatusBarText;
+       div.onmouseout = colorPickerHideStatusBarText;
+       webColorDiv.appendChild(div);
+      }
+    }
+  }
+}
+               
+function createNamedColors(inputObj){
+  var namedColorDiv = document.createElement('DIV');
+  namedColorDiv.style.paddingTop = '1px';
+  namedColorDiv.style.display='none';
+  inputObj.appendChild(namedColorDiv);
+  for(var no=0;no<namedColors.length;no++){
+    var color = namedColorRGB[no];
+    var div = document.createElement('DIV');
+    div.style.backgroundColor=color;
+    div.innerHTML = '<span></span>';
+    div.className='colorSquare';
+    div.title = namedColors[no];       
+    div.onclick = chooseColor;
+    div.onmouseover = colorPickerShowStatusBarText;
+    div.onmouseout = colorPickerHideStatusBarText;
+    div.setAttribute('rgbColor',color);
+    namedColorDiv.appendChild(div);                            
+  }    
+       
+}
+       
+function colorPickerHideStatusBarText()
+{
+  document.getElementById('colorPicker_statusBarTxt').innerHTML = '&nbsp;';
+}
+       
+function colorPickerShowStatusBarText()
+{
+  var txt = this.getAttribute('rgbColor');
+  if(this.title.indexOf('#')<0)txt = txt + " (" + this.title + ")";
+  document.getElementById('colorPicker_statusBarTxt').innerHTML = txt; 
+}
+       
+function createAllColorDiv(inputObj){
+  var allColorDiv = document.createElement('DIV');
+  allColorDiv.style.display='none';
+  allColorDiv.className = 'js_color_picker_allColorDiv';
+  allColorDiv.style.paddingLeft = '3px';
+  allColorDiv.style.paddingTop = '5px';
+  allColorDiv.style.paddingBottom = '5px';
+  inputObj.appendChild(allColorDiv);   
+               
+  var labelDiv = document.createElement('DIV');
+  labelDiv.className='colorSliderLabel';
+  labelDiv.innerHTML = 'R';
+  allColorDiv.appendChild(labelDiv);   
+               
+  var innerDiv = document.createElement('DIV');
+  innerDiv.className = 'colorSlider';
+  innerDiv.id = 'sliderRedColor';              
+  allColorDiv.appendChild(innerDiv);           
+               
+  var innerDivInput = document.createElement('DIV');
+  innerDivInput.className='colorInput';
+               
+  var input = document.createElement('INPUT');
+  input.id = 'js_color_picker_red_color';
+  input.maxlength = 3;
+  input.style.width = '48px';
+  input.style.fontSize = '11px';
+  input.name = 'redColor';
+  input.value = 0;
+               
+  innerDivInput.appendChild(input);
+  allColorDiv.appendChild(innerDivInput);
+
+  var labelDiv = document.createElement('DIV');
+  labelDiv.className='colorSliderLabel';
+  labelDiv.innerHTML = 'G';
+  allColorDiv.appendChild(labelDiv);   
+                               
+  var innerDiv = document.createElement('DIV');
+  innerDiv.className = 'colorSlider';
+  innerDiv.id = 'sliderGreenColor';            
+  allColorDiv.appendChild(innerDiv);           
+               
+  var innerDivInput = document.createElement('DIV');
+  innerDivInput.className='colorInput';
+               
+  var input = document.createElement('INPUT');
+  input.id = 'js_color_picker_green_color';
+  input.maxlength = 3;
+  input.style.width = '48px';
+  input.style.fontSize = '11px';
+  input.name = 'GreenColor';
+  input.value = 0;
+               
+  innerDivInput.appendChild(input);
+  allColorDiv.appendChild(innerDivInput);
+               
+  var labelDiv = document.createElement('DIV');
+  labelDiv.className='colorSliderLabel';
+  labelDiv.innerHTML = 'B';
+  allColorDiv.appendChild(labelDiv);                   
+  var innerDiv = document.createElement('DIV');
+  innerDiv.className = 'colorSlider';
+  innerDiv.id = 'sliderBlueColor';             
+  allColorDiv.appendChild(innerDiv);           
+               
+  var innerDivInput = document.createElement('DIV');
+  innerDivInput.className='colorInput';
+               
+  var input = document.createElement('INPUT');
+  input.id = 'js_color_picker_blue_color';
+  input.maxlength = 3;
+  input.style.width = '48px';
+  input.style.fontSize = '11px';
+  input.name = 'BlueColor';
+  input.value = 0;
+               
+  innerDivInput.appendChild(input);
+  allColorDiv.appendChild(innerDivInput);
+
+       
+  var colorPreview = document.createElement('DIV');
+  colorPreview.className='colorPreviewDiv';
+  colorPreview.id = 'colorPreview';
+  colorPreview.style.backgroundColor = '#000000';
+  colorPreview.innerHTML = '<span></span>';    
+  colorPreview.title = 'Click on me to assign color';  
+  allColorDiv.appendChild(colorPreview);
+  colorPreview.onclick = chooseColorSlider;
+               
+  var colorCodeDiv = document.createElement('DIV');
+  colorCodeDiv.className='colorCodeDiv';               
+  var input = document.createElement('INPUT');
+  input.id = 'js_color_picker_color_code';
+               
+  colorCodeDiv.appendChild(input);
+  input.maxLength = 7;
+  input.style.fontSize = '11px';
+  input.style.width = '48px';          
+  input.value = '#000000';
+  input.onchange = setPreviewColorFromTxt;
+  input.onblur = setPreviewColorFromTxt;
+  allColorDiv.appendChild(colorCodeDiv);
+               
+  var clearingDiv = document.createElement('DIV');
+  clearingDiv.style.clear = 'both';
+  allColorDiv.appendChild(clearingDiv);
+               
+               
+  form_widget_amount_slider('sliderRedColor',document.getElementById('js_color_picker_red_color'),170,0,255,"setColorByRGB()");
+  form_widget_amount_slider('sliderGreenColor',document.getElementById('js_color_picker_green_color'),170,0,255,"setColorByRGB()");
+  form_widget_amount_slider('sliderBlueColor',document.getElementById('js_color_picker_blue_color'),170,0,255,"setColorByRGB()");
+}
+       
+function setPreviewColorFromTxt()
+{
+  if(this.value.match(/\#[0-9A-F]{6}/g)){
+    document.getElementById('colorPreview').style.backgroundColor=this.value;
+    var r = this.value.substr(1,2);
+    var g = this.value.substr(3,2);
+    var b = this.value.substr(5,2);
+    document.getElementById('js_color_picker_red_color').value = baseConverter(r,16,10);
+    document.getElementById('js_color_picker_green_color').value = baseConverter(g,16,10);
+    document.getElementById('js_color_picker_blue_color').value = baseConverter(b,16,10);
+                       
+    positionSliderImage(false,1,document.getElementById('js_color_picker_red_color'));
+    positionSliderImage(false,2,document.getElementById('js_color_picker_green_color'));
+    positionSliderImage(false,3,document.getElementById('js_color_picker_blue_color'));
+  }
+               
+}
+       
+function chooseColor()
+{
+  onChooseColor(this.getAttribute('rgbColor'));
+  //           color_picker_form_field.value = this.getAttribute('rgbColor');
+  //           color_picker_div.style.display='none';
+}
+       
+function createStatusBar(inputObj)
+{
+  var div = document.createElement('DIV');
+  div.className='colorPicker_statusBar';       
+  var innerSpan = document.createElement('SPAN');
+  innerSpan.id = 'colorPicker_statusBarTxt';
+  div.appendChild(innerSpan);
+  inputObj.appendChild(div);
+}
+       
+function chooseColorSlider()
+{
+  onChooseColor(document.getElementById('js_color_picker_color_code').value);
+  //           color_picker_form_field.value = document.getElementById('js_color_picker_color_code').value;
+  //           color_picker_div.style.display='none';          
+}
+       
+       
+function showColorPicker()
+{
+  if(!color_picker_div){
+    color_picker_div = document.createElement('DIV');
+    color_picker_div.id = 'dhtmlgoodies_colorPicker';
+    document.body.appendChild(color_picker_div);
+    createColorPickerTopRow(color_picker_div);                 
+    var contentDiv = document.createElement('DIV');
+    contentDiv.id = 'color_picker_content';
+    color_picker_div.appendChild(contentDiv);                  
+    createWebColors(contentDiv);
+    createNamedColors(contentDiv);
+    createAllColorDiv(contentDiv);
+    createStatusBar(color_picker_div);                 
+  }            
+  //           if(color_picker_div.style.display=='none' || color_picker_active_input!=inputObj)color_picker_div.style.display='block'; else color_picker_div.style.display='none';            
+  //           color_picker_div.style.left = colorPickerGetLeftPos(inputObj) + 'px';
+  //           color_picker_div.style.top = colorPickerGetTopPos(inputObj) + inputObj.offsetHeight + 2 + 'px';
+  //           color_picker_form_field = formField;
+  //           color_picker_active_input = inputObj;           
+}
+
+function setColorByRGB()
+{
+  var formObj = document.forms[0];     
+  var r = document.getElementById('js_color_picker_red_color').value.replace(/[^\d]/,'');
+  var g = document.getElementById('js_color_picker_green_color').value.replace(/[^\d]/,'');
+  var b = document.getElementById('js_color_picker_blue_color').value.replace(/[^\d]/,'');             
+  if(r/1>255)r=255;
+  if(g/1>255)g=255;
+  if(b/1>255)b=255;
+  r = baseConverter(r,10,16) + '';
+  g = baseConverter(g,10,16) + '';
+  b = baseConverter(b,10,16) + '';
+  if(r.length==1)r = '0' + r;
+  if(g.length==1)g = '0' + g;
+  if(b.length==1)b = '0' + b;
+
+  document.getElementById('colorPreview').style.backgroundColor = '#' + r + g + b;
+  document.getElementById('js_color_picker_color_code').value = '#' + r + g + b;               
+}
diff --git a/UI/WebServerResources/slider_handle.gif b/UI/WebServerResources/slider_handle.gif
new file mode 100644 (file)
index 0000000..28de719
Binary files /dev/null and b/UI/WebServerResources/slider_handle.gif differ
diff --git a/UI/WebServerResources/tab_.gif b/UI/WebServerResources/tab_.gif
deleted file mode 100644 (file)
index ad720a0..0000000
Binary files a/UI/WebServerResources/tab_.gif and /dev/null differ
diff --git a/UI/WebServerResources/tab_selected.gif b/UI/WebServerResources/tab_selected.gif
deleted file mode 100644 (file)
index 2cbdea6..0000000
Binary files a/UI/WebServerResources/tab_selected.gif and /dev/null differ