]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1155 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Fri, 24 Aug 2007 21:33:47 +0000 (21:33 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Fri, 24 Aug 2007 21:33:47 +0000 (21:33 +0000)
34 files changed:
ChangeLog
Scripts/sql-update-20070822.sh [new file with mode: 0755]
SoObjects/Appointments/GNUmakefile
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Appointments/SOGoAppointmentObject.m
SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html
SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html
SoObjects/Appointments/SOGoAptMailFrenchRemoval.wo/SOGoAptMailFrenchRemoval.html
SoObjects/Appointments/SOGoAptMailFrenchUpdate.wo/SOGoAptMailFrenchUpdate.html
SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html
SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html
SoObjects/Appointments/SOGoAptMailGermanRemoval.wo/SOGoAptMailGermanRemoval.html
SoObjects/Appointments/SOGoAptMailGermanUpdate.wo/SOGoAptMailGermanUpdate.html
SoObjects/Appointments/SOGoAptMailNotification.h
SoObjects/Appointments/SOGoAptMailNotification.m
SoObjects/Contacts/SOGoContactFolders.m
SoObjects/Mailer/SOGoDraftObject.m
SoObjects/Mailer/SOGoMailFolder.m
SoObjects/Mailer/bundle-info.plist [new file with mode: 0644]
SoObjects/SOGo/NSString+Utilities.h
SoObjects/SOGo/NSString+Utilities.m
SoObjects/SOGo/SOGoFolder.m
SoObjects/SOGo/SOGoUserFolder.m
UI/Contacts/German.lproj/Localizable.strings [new file with mode: 0644]
UI/MailPartViewers/UIxMailPartViewer.m
UI/Scheduler/UIxAppointmentEditor.m
UI/Scheduler/UIxTaskEditor.m
UI/Templates/MailerUI/UIxMailEditor.wox
UI/WebServerResources/ContactsUI.css
UI/WebServerResources/MailerUI.css
UI/WebServerResources/SchedulerUI.css
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxMailEditor.css
UI/WebServerResources/UIxMailView.js [new file with mode: 0644]

index 0bcd7abee819e5e782999b2ded6d2c97c7238c23..6c30d788f91489c6536a9ab81a0e7c454a7a89b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2007-08-24  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -lookupCalendarFolderForUID:uid]): add
+       "personal" to the ocs path of the appointment folder.
+
+       * UI/MailPartViewers/UIxMailPartViewer.m ([UIxMailPartViewer
+       -flatContentAsString]): use latin1 when the encoding is not
+       specified, and to reencode data chunk which were not correctly
+       decoded with the original charset.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m ([SOGoAppointmentFolder -aclUsersForObjectAtPath:objectPathArray])
+       ([SOGoAppointmentFolder -aclsForUser:uidforObjectAtPath:objectPathArray])
+       ([SOGoAppointmentFolder -setRoles:rolesforUser:uidforObjectAtPath:objectPathArray])
+       ([SOGoAppointmentFolder
+       -removeAclsForUsers:usersforObjectAtPath:objectPathArray]):
+       override those methods to use the "personal" additional directory.
+
+       * SoObjects/SOGo/SOGoUserFolder.m ([-ocsPrivateCalendarPath]):
+       append "/personal" to the calendar path to simulate a single
+       calendar in a choice of many.
+
+       * SoObjects/Mailer/SOGoMailFolder.m ([SOGoMailFolder
+       -lookupName:_keyinContext:acquire:_acquire]): moved the lookup
+       methods back here. Moved the folder existence check here, and do
+       it on self only when the lookup happens for a non-folder object.
+       This permits to accept entries for folders with parents who
+       don't really exist.
+
+2007-08-23  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor
+       -shouldTakeValuesFromRequest:requestinContext:context]): same as
+       below.
+
+       * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
+       -shouldTakeValuesFromRequest:requestinContext:context]):
+       redesigned method since any method called can be received from a
+       POST or a GET. Instead we check the method call itself and we
+       accept only if it has the "save" prefix.
+
+       * SoObjects/Appointments/SOGoAptMailNotification.m
+       ([SOGoAptMailNotification -getSubject]): returns the subject an a
+       quoted-printable encoded string, if needed.
+
+       * SoObjects/Mailer/SOGoDraftObject.m ([NSString
+       -asQPSubjectString:encoding]): moved method into
+       NSString+Utilities.m.
+
 2007-08-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/PreferencesUI/UIxPreferences.m ([UIxPreferences
diff --git a/Scripts/sql-update-20070822.sh b/Scripts/sql-update-20070822.sh
new file mode 100755 (executable)
index 0000000..80a41a2
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+# this script only work with PostgreSQL
+
+defaultusername=$USER
+defaulthostname=localhost
+defaultdatabase=$USER
+indextable=sogo_folder_info
+
+read -p "Username ($defaultusername): " username
+read -p "Hostname ($defaulthostname): " hostname
+read -p "Database ($defaultdatabase): " database
+
+if [ -z "$username" ]
+then
+  username=$defaultusername
+fi
+if [ -z "$hostname" ]
+then
+  hostname=$defaulthostname
+fi
+if [ -z "$database" ]
+then
+  database=$defaultdatabase
+fi
+
+echo ""
+echo "You will now be requested your password twice..."
+echo "After that, a list of SQL operations will scroll."
+echo ""
+
+sqlscript=""
+
+function addField() {
+    oldIFS="$IFS"
+    IFS=" "
+    part="`echo -e \"ALTER TABLE $table ADD COLUMN c_deleted INTEGER;\\n\"`";
+    sqlscript="$sqlscript$part"
+    IFS="$oldIFS"
+}
+
+tables=`psql -t -U $username -h $hostname $database -c "select split_part(c_location, '/', 5) from $indextable where c_folder_type != 'Container';"`
+
+for table in $tables;
+do
+  addField
+done
+
+sqlscript="$sqlscript;update $indextable set c_path4 = 'personal', c_path = '/Users/' || c_path2 || '/Calendar/personal' where c_path3 = 'Calendar' and c_path4 is null;"
+
+function updateCalendarLocation() {
+    oldIFS="$IFS"
+    IFS=" "
+    user="`echo $table | cut -f 1 -d :`"
+    tablename="`echo $table | cut -f 2 -d :`"
+    newstart="/$user/Calendar/personal";
+    part="update $tablename set c_object = replace(c_object, '/$user/Calendar', '$newstart') where c_object not like '$newstart%';";
+    sqlscript="$sqlscript$part"
+    IFS="$oldIFS"
+}
+
+tables=`psql -t -U $username -h $hostname $database -c "select c_path2 || ':' || split_part(c_acl_location, '/', 5) from $indextable where c_folder_type = 'Appointment';"`
+for table in $tables;
+do
+  updateCalendarLocation
+done
+
+echo "$sqlscript" | psql -q -e -U $username -h $hostname $database > /dev/null
+
+echo "Please ignore the errors above. They just mean that the migration was already done for the elements in question.";
\ No newline at end of file
index 4e3d3255d6d336066b8c904e36d8ea985c697717..789501a3d8fdcc8246449072ca5dc921d0d7e10f 100644 (file)
@@ -32,13 +32,17 @@ Appointments_RESOURCE_FILES +=              \
 
 Appointments_COMPONENTS +=     \
        SOGoAptMailEnglishInvitation.wo \
-       SOGoAptMailFrenchInvitation.wo  \
        SOGoAptMailEnglishUpdate.wo     \
-       SOGoAptMailFrenchUpdate.wo      \
        SOGoAptMailEnglishRemoval.wo    \
-       SOGoAptMailFrenchRemoval.wo     \
        SOGoAptMailEnglishDeletion.wo   \
+       SOGoAptMailFrenchInvitation.wo  \
+       SOGoAptMailFrenchUpdate.wo      \
+       SOGoAptMailFrenchRemoval.wo     \
        SOGoAptMailFrenchDeletion.wo    \
+       SOGoAptMailGermanInvitation.wo  \
+       SOGoAptMailGermanUpdate.wo      \
+       SOGoAptMailGermanRemoval.wo     \
+       SOGoAptMailGermanDeletion.wo    \
 
 -include GNUmakefile.preamble
 include $(GNUSTEP_MAKEFILES)/wobundle.make
index 5e7955a7e61022b8971b4268008b1b160be3e8ac..9fa1695fc93fc74706d8dbcb6fdd4ef308c40bf8 100644 (file)
@@ -1029,7 +1029,7 @@ static NSNumber   *sharedYes = nil;
   calendarFolder = [SOGoAppointmentFolder objectWithName: @"Calendar"
                                           inContainer: userFolder];
   [calendarFolder
-    setOCSPath: [NSString stringWithFormat: @"/Users/%@/Calendar", uid]];
+    setOCSPath: [NSString stringWithFormat: @"/Users/%@/Calendar/personal", uid]];
   [calendarFolder setOwner: uid];
 
   return calendarFolder;
@@ -1297,4 +1297,49 @@ static NSNumber   *sharedYes = nil;
   return @"IPF.Appointment";
 }
 
+/* hack until we permit more than 1 cal per user */
+- (NSArray *) _fixedPath: (NSArray *) objectPath
+{
+  NSMutableArray *newPath;
+
+  newPath = [NSMutableArray arrayWithArray: objectPath];
+  if ([newPath count] > 2)
+    {
+      if (![[newPath objectAtIndex: 2] isEqualToString: @"personal"])
+       [newPath insertObject: @"personal" atIndex: 2];
+    }
+  else
+    [newPath addObject: @"personal"];
+
+  return newPath;
+}
+
+- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray
+{
+  return [super aclUsersForObjectAtPath: [self _fixedPath: objectPathArray]];
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+          forObjectAtPath: (NSArray *) objectPathArray
+{
+  return [super aclsForUser: uid
+               forObjectAtPath: [self _fixedPath: objectPathArray]];
+}
+
+- (void) setRoles: (NSArray *) roles
+          forUser: (NSString *) uid
+  forObjectAtPath: (NSArray *) objectPathArray
+{
+  [super setRoles: roles
+        forUser: uid
+        forObjectAtPath: [self _fixedPath: objectPathArray]];
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+            forObjectAtPath: (NSArray *) objectPathArray
+{
+  [super removeAclsForUsers: users
+        forObjectAtPath: [self _fixedPath: objectPathArray]];
+}
+
 @end /* SOGoAppointmentFolder */
index 9b1b334fe93cb47e1c818fae707284ac9ddb2b04..1058df10c3b5e2018c5c2130507abd699ffd1519 100644 (file)
 
 /* store in all the other folders */
 
-- (NSException *)saveContentString:(NSString *)_iCal inUIDs:(NSArray *)_uids {
+- (NSException *) saveContentString: (NSString *) _iCal
+                            inUIDs: (NSArray *) _uids
+{
   NSEnumerator *e;
   id folder;
   NSException *allErrors = nil;
index 38d29abb38211a0e7d4cd57cd55fa1fcadfd9c6c..780726512cdb8ff3cf6794b4465feb4d2aed9458 100644 (file)
@@ -1,4 +1,4 @@
-<#IsSubject>Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé</#IsSubject>
+<#IsSubject>Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé</#IsSubject>
 <#IsBody>
-Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé par <#Organizer />.
+Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé par <#Organizer />.
 </#IsBody>
index 271a375c9746da444f13ee7957b8d0b0fabb8b03..b3313946fd1527a573f92b846e085049c59f2bad 100644 (file)
@@ -1,7 +1,7 @@
-<#IsSubject>Rendez-vous le <#AptStartDate /> à <#AptStartTime /></#IsSubject>
+<#IsSubject>Rendez-vous le <#AptStartDate /> à <#AptStartTime /></#IsSubject>
 <#IsBody>
-Vous êtes invité par <#Organizer /> à une réunion.
+Vous êtes invité par <#Organizer /> à une réunion.
 <#HasHomePageURL>
-Veuillez donner votre réponse à l'adresse <#HomePageURL />.
+Veuillez donner votre réponse à l'adresse <#HomePageURL />.
 </#HasHomePageURL>
 </#IsBody>
index bbe73df30baea22651e8d6faa73f42ee2be50e8c..1cf438f7e7328110cddc6835b61483351da3fe29 100644 (file)
@@ -1,4 +1,4 @@
-<#IsSubject>Supprimé de la réunion du <#AptStartDate /> à <#AptStartTime /></#IsSubject>
+<#IsSubject>Supprimé de la réunion du <#AptStartDate /> à <#AptStartTime /></#IsSubject>
 <#IsBody>
-Vous ne faites plus parti de la liste des invités de la réunion du <#AptStartDate /> à <#AptStartTime /> organisée par <#Organizer />.
+Vous ne faites plus parti de la liste des invités de la réunion du <#AptStartDate /> à <#AptStartTime /> organisée par <#Organizer />.
 </#IsBody>
index 901e34e14d38326b56c6486f3ee3a67bd36a1b94..c008d38040f604ecec7e308b4d94aa95fab114f4 100644 (file)
@@ -1,5 +1,5 @@
-<#IsSubject>Rendez-vous du <#OldAptStartDate /> à <#OldAptStartTime /> modifié</#IsSubject>
+<#IsSubject>Rendez-vous du <#OldAptStartDate /> à <#OldAptStartTime /> modifié</#IsSubject>
 <#IsBody>
-La réunion qui devait se dérouler le <#OldAptStartDate /> à <#OldAptStartTime /> est maintenant prévue le <#NewAptStartDate /> à <#NewAptStartTime />.
-Vous êtes invité  à accepter ou refuser de participer à la réunion pour cette nouvelle date à l'adresse <#HomePageURL />.
+La réunion qui devait se dérouler le <#OldAptStartDate /> à <#OldAptStartTime /> est maintenant prévue le <#NewAptStartDate /> à <#NewAptStartTime />.
+Vous êtes invité  à accepter ou refuser de participer à la réunion pour cette nouvelle date à l'adresse <#HomePageURL />.
 </#IsBody>
index 5653d744720b12c264463d60ed219b6ba71daafe..edbc3088270acf37f3378fdac6123e782d4e40da 100644 (file)
@@ -1,4 +1,4 @@
-<#IsSubject>Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde gelöscht.</#IsSubject>
+<#IsSubject>Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde gelöscht.</#IsSubject>
 <#IsBody>
-Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde von <#Organizer /> gelöscht.
+Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde von <#Organizer /> gelöscht.
 </#IsBody>
index 982c66a1a8c221c07e4c332ae6969f1411760525..383fbb856871d337c169ec60942486bab99bbb46 100644 (file)
@@ -1,7 +1,7 @@
 <#IsSubject>Termin am <#AptStartDate /> um <#AptStartTime /></#IsSubject>
 <#IsBody>
-<#Organizer /> lädt Sie zu einem Termin am <#AptStartDate /> um <#AptStartTime /> ein.
+<#Organizer /> lädt Sie zu einem Termin am <#AptStartDate /> um <#AptStartTime /> ein.
 <#HasHomePageURL>
-Bitte benutzen Sie folgende URL, um anzugeben, ob Sie an dem Termin teilnehmen können: <#HomePageURL />.
+Bitte benutzen Sie folgende URL, um anzugeben, ob Sie an dem Termin teilnehmen können: <#HomePageURL />.
 </#HasHomePageURL>
 </#IsBody>
index 3133ccc63d42fbb5fbad298ea018a9046fa426cf..3261311e5e0f1fb9f5b4ea9f5bcf78ed72a564e3 100644 (file)
@@ -1,4 +1,4 @@
-<#IsSubject>Von dem Termin am <#AptStartDate /> um <#AptStartTime /> gelöscht</#IsSubject>
+<#IsSubject>Von dem Termin am <#AptStartDate /> um <#AptStartTime /> gelöscht</#IsSubject>
 <#IsBody>
 Sie sind nicht mehr eingeladen zu dem Termin am <#AptStartDate /> um <#AptStartTime /> organisiert von <#Organizer />.
 </#IsBody>
index b0fd4dc9357d2df860baf0a1962fdb648c184e34..f5ce36672081754acaed5ddc027a5193fc972aad 100644 (file)
@@ -1,5 +1,5 @@
-<#IsSubject>Veränderung des Termins am <#OldAptStartDate /> um <#OldAptStartTime /></#IsSubject>
+<#IsSubject>Veränderung des Termins am <#OldAptStartDate /> um <#OldAptStartTime /></#IsSubject>
 <#IsBody>
-Der Termin, der ursprünglich am <#OldAptStartDate /> um <#OldAptStartTime /> stattfinden sollte, ist jetzt für den <#NewAptStartDate /> um <#NewAptStartTime /> geplant.
-Bitte geben Sie an folgender URL an, ob Sie an diesem Termin zum neuen Datum teilnehmen können: <#HomePageURL />.
+Der Termin, der ursprünglich am <#OldAptStartDate /> um <#OldAptStartTime /> stattfinden sollte, ist jetzt für den <#NewAptStartDate /> um <#NewAptStartTime /> geplant.
+Bitte geben Sie an folgender URL an, ob Sie an diesem Termin zum neuen Datum teilnehmen können: <#HomePageURL />.
 </#IsBody>
index 9345717579e0cefb1cc8ab87d0b9e27352d404c6..ba774b185287c324774d6003f0282b2fa3adda47 100644 (file)
 - (id) newApt;
 - (void) setNewApt: (iCalEntityObject *) _newApt;
 
-- (NSString *)homePageURL;
-- (void)setHomePageURL: (NSString *)_homePageURL;
+- (NSString *) homePageURL;
+- (void) setHomePageURL: (NSString *) _homePageURL;
 
-- (NSTimeZone *)viewTZ;
-- (void)setViewTZ:(NSTimeZone *)_viewTZ;
+- (NSTimeZone *) viewTZ;
+- (void) setViewTZ: (NSTimeZone *) _viewTZ;
 
 /* Helpers */
 
-- (NSCalendarDate *)oldStartDate;
-- (NSCalendarDate *)newStartDate;
+- (NSCalendarDate *) oldStartDate;
+- (NSCalendarDate *) newStartDate;
 
 /* Content Generation */
 
-- (NSString *)getSubject;
-- (NSString *)getBody;
+- (NSString *) getSubject;
+- (NSString *) getBody;
   
 @end
 
index 788669afda54b7f090fd99dc111c4dd799de6c84..5c6b2c4f0334a1bb5f653a85794d82f80e78ef31 100644 (file)
@@ -28,6 +28,8 @@
 #import <NGExtensions/NSObject+Logs.h>
 #import <NGCards/iCalEntityObject.h>
 
+#import <SoObjects/SOGo/NSString+Utilities.h>
+
 #import "SOGoAptMailNotification.h"
 
 @interface SOGoAptMailNotification (PrivateAPI)
@@ -141,7 +143,8 @@ static NSTimeZone     *EST = nil;
                           [self name]];
     subject = @"ERROR: missing subject!";
   }
-  return subject;
+
+  return [subject asQPSubjectString: @"utf-8"];
 }
 
 - (NSString *)getBody {
index f166515a056d2c1c20f23be93e92b045528a7263..215870978fff5d63b09c6503919420c9ccdc6497 100644 (file)
   return nil;
 }
 
-// - (NSString *) roleOfUser: (NSString *) uid
-// {
-//   NSArray *roles, *traversalPath;
-//   NSString *objectName, *role;
-
-//   role = nil;
-//   traversalPath = [context objectForKey: @"SoRequestTraversalPath"];
-//   if ([traversalPath count] > 2)
-//     {
-//       objectName = [traversalPath objectAtIndex: 2];
-//       roles = [[context activeUser]
-//             rolesForObject: [self lookupName: objectName
-//                                   inContext: context
-//                                   acquire: NO]
-//             inContext: context];
-//       if ([roles containsObject: SOGoRole_Assistant]
-//       || [roles containsObject: SOGoRole_Delegate])
-//     role = SOGoRole_Assistant;
-//     }
-
-//   return role;
-// }
-
 - (BOOL) davIsCollection
 {
   return YES;
index 6c49beb97d42bd72b4b67ca7fd384c980b3f4f0b..a8a6313510e89b82fbabdd9e1d916b627bdbef0a 100644 (file)
@@ -53,6 +53,7 @@
 
 #import <SoObjects/SOGo/NSArray+Utilities.h>
 #import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+#import <SoObjects/SOGo/NSString+Utilities.h>
 #import <SoObjects/SOGo/SOGoMailer.h>
 #import <SoObjects/SOGo/SOGoUser.h>
 #import "SOGoMailAccount.h"
@@ -66,36 +67,6 @@ static NSString *contentTypeValue = @"text/plain; charset=utf-8";
 static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc", 
                                 @"from", @"replyTo", nil};
 
-@interface NSString (NGMimeHelpers)
-
-- (NSString *) asQPSubjectString: (NSString *) encoding;
-
-@end
-
-@implementation NSString (NGMimeHelpers)
-
-- (NSString *) asQPSubjectString: (NSString *) encoding;
-{
-  NSString *qpString, *subjectString;
-  NSData *subjectData, *destSubjectData;
-
-  subjectData = [self dataUsingEncoding: NSUTF8StringEncoding];
-  destSubjectData = [subjectData dataByEncodingQuotedPrintable];
-
-  qpString = [[NSString alloc] initWithData: destSubjectData
-                              encoding: NSASCIIStringEncoding];
-  [qpString autorelease];
-  if ([qpString length] > [self length])
-    subjectString = [NSString stringWithFormat: @"=?%@?Q?%@?=",
-                             encoding, qpString];
-  else
-    subjectString = self;
-
-  return subjectString;
-}
-
-@end
-
 @implementation SOGoDraftObject
 
 static NGMimeType  *TextPlainType  = nil;
index 7087a17113f9fec456b38084576a9978a96efb4b..babd5684fff939f5d3e461d212874272485651c1 100644 (file)
@@ -225,42 +225,6 @@ static BOOL useAltNamespace = NO;
 
 /* name lookup */
 
-- (id) lookupImap4Folder: (NSString *) _key
-              inContext: (id) _ctx
-{
-  // TODO: we might want to check for existence prior controller creation
-  NSURL *sf;
-  SOGoMailFolder *newFolder;
-
-  /* check whether URL exists */
-  
-  sf = [self imap4URL];
-  sf = [NSURL URLWithString: [_key substringFromIndex: 6]
-             relativeToURL: sf];
-
-// -  sf = [NSURL URLWithString:[[sf path] stringByAppendingPathComponent:_key]
-// -         relativeToURL:sf];
-
-  if ([[self imap4Connection] doesMailboxExistAtURL: sf])
-    newFolder = [SOGoMailFolder objectWithName: _key inContainer: self];
-  else
-    newFolder = nil;
-  /* 
-     We may not return 404, confuses path traversal - but we still do in the
-     calling method. Probably the traversal process should be fixed to
-     support 404 exceptions (as stop traversal _and_ acquisition).
-  */
-  
-  return newFolder;
-}
-
-- (id) lookupImap4Message: (NSString *) _key
-               inContext: (id) _ctx
-{
-  // TODO: we might want to check for existence prior controller creation
-  return [SOGoMailObject objectWithName: _key inContainer: self];
-}
-
 - (id) lookupName: (NSString *) _key
        inContext: (id)_ctx
          acquire: (BOOL) _acquire
@@ -268,13 +232,18 @@ static BOOL useAltNamespace = NO;
   id obj;
 
   if ([_key hasPrefix: @"folder"])
-    obj = [self lookupImap4Folder: _key inContext: _ctx];
+    obj = [SOGoMailFolder objectWithName: _key inContainer: self];
   else
     {
-      if (isdigit ([_key characterAtIndex: 0]))
-       obj = [self lookupImap4Message: _key inContext: _ctx];
+      if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]])
+       {
+         if (isdigit ([_key characterAtIndex: 0]))
+           obj = [SOGoMailObject objectWithName: _key inContainer: self];
+         else
+           obj = [super lookupName: _key inContext: _ctx acquire: NO];
+       }
       else
-       obj = [super lookupName: _key inContext: _ctx acquire: NO];
+       obj = nil;
     }
 
   if (!obj && _acquire)
diff --git a/SoObjects/Mailer/bundle-info.plist b/SoObjects/Mailer/bundle-info.plist
new file mode 100644 (file)
index 0000000..2c63c08
--- /dev/null
@@ -0,0 +1,2 @@
+{
+}
index 7cd8042b48ebef16675bcae41517d8174ad8c813..0f2e95a99d4b4bd080a091e2069e70d79813fd1f 100644 (file)
@@ -46,6 +46,8 @@
 /* bare email addresses */
 - (NSString *) pureEMailAddress;
 
+- (NSString *) asQPSubjectString: (NSString *) encoding;
+
 #ifndef GNUSTEP_BASE_LIBRARY
 - (BOOL) boolValue;
 #endif
index 38c09bad5f40e83f130a5b4f0f3ec61c9d51d1af..bb8ece23c54e7f1b76b38f1b5d91b015892ab170 100644 (file)
@@ -268,6 +268,26 @@ static NSMutableCharacterSet *urlAfterEndingChars = nil;
   return pureAddress;
 }
 
+- (NSString *) asQPSubjectString: (NSString *) encoding
+{
+  NSString *qpString, *subjectString;
+  NSData *subjectData, *destSubjectData;
+
+  subjectData = [self dataUsingEncoding: NSUTF8StringEncoding];
+  destSubjectData = [subjectData dataByEncodingQuotedPrintable];
+
+  qpString = [[NSString alloc] initWithData: destSubjectData
+                              encoding: NSASCIIStringEncoding];
+  [qpString autorelease];
+  if ([qpString length] > [self length])
+    subjectString = [NSString stringWithFormat: @"=?%@?Q?%@?=",
+                             encoding, qpString];
+  else
+    subjectString = self;
+
+  return subjectString;
+}
+
 #if LIB_FOUNDATION_LIBRARY
 - (BOOL) boolValue
 {
index d6676c0e54b72c23cf237df30c90caf08d4e47c1..20a3b8944cba79139f75160b10da6e34c00ba18e 100644 (file)
@@ -42,6 +42,7 @@
 #import <GDLContentStore/GCSFolderType.h>
 #import <SaxObjC/XMLNamespaces.h>
 
+#import "NSArray+Utilities.h"
 #import "NSString+Utilities.h"
 
 #import "SOGoPermissions.h"
@@ -211,7 +212,7 @@ static NSString *defaultUserID = @"<default>";
     }
   if ([records isKindOfClass: [NSException class]])
     return records;
-  return [records valueForKey: @"c_name"];
+  return [records objectsForKey: @"c_name"];
 }
 
 - (BOOL) nameExistsInFolder: (NSString *) objectName
index 933779c33168ff8dd6312322e6005c6caf937028..8db12b30eaa2aa70ee77746308a0722d64558e88 100644 (file)
 
 - (NSString *) ocsPrivateCalendarPath
 {
-  return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
+  return [[self ocsUserPath] stringByAppendingString:@"/Calendar/personal"];
 }
 
 - (NSString *) ocsPrivateContactsPath
diff --git a/UI/Contacts/German.lproj/Localizable.strings b/UI/Contacts/German.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..9f4500a
--- /dev/null
@@ -0,0 +1,129 @@
+/* this file is in UTF-8 format! */
+
+"Contact" = "Kontakt";
+"Address" = "Adresse";
+"Other" = "Sonstiges";
+
+"Name"              = "Name";
+"Internet"          = "Internet";
+"Phones"            = "Telefon";
+"Home" = "Privat";
+"Work" = "Dienstlich";
+
+"Address Books"      = "Adressbücher";
+"Addresses"         = "Adresses";
+"Update" = "Speichern";
+"Cancel"            = "Abbrechen";
+"Common"            = "Name";
+"Contact editor"    = "Éditer le contact";
+"Contact viewer"    = "Visualiser le contact";
+"Email"             = "E-Mail";
+"Screen Name"      = "Messenger-Name";
+"Extended"          = "Informations complémentaires";
+"Fax"               = "Fax";
+"Firstname"         = "Vorname";
+"HomePhone"         = "Privat";
+"Lastname"          = "Name";
+"Location"          = "Lieux";
+"MobilePhone"       = "Mobil";
+"OfficePhone"       = "Dienstlich";
+"Organization"      = "Organisation";
+"Work Phone" = "Dienstlich";
+"Phone"             = "Telefon";
+"Postal"            = "Professionnelle";
+"Save"              = "Speichern";
+"URL"               = "Webseite";
+"Unit"              = "Abteilung";
+"delete"            = "Löschen";
+"edit"              = "Éditer";
+"invalidemailwarn"  = "Champ de l'email invalide, continuer quand même ?";
+"new"               = "Neu";
+
+"htmlMailFormat_UNKNOWN" = "Unbekannt";
+"htmlMailFormat_FALSE" = "Reintext";
+"htmlMailFormat_TRUE" = "HTML";
+
+"Name or Email" = "Name oder E-Mail";
+"Personal Addressbook" = "Adresses personnelles";
+"Search in Addressbook" = "Carnet d'adresses...";
+
+"New Card" = "Neue Karte";
+"New List" = "Neue Liste";
+"Modify" = "Eigenschaften";
+"Sharing..." = "Benutzerrechte...";
+"Write" = "Verfassen";
+"Delete" = "Löschen";
+"Instant Message" = "Messenger";
+"Add..." = "Hinzufügen...";
+"Remove" = "Löschen";
+
+"Preferred" = "Préféré";
+"Card for %@" = "%@";
+"Display:" = "Anzeigename:";
+"Display Name:" = "Anzeigename:";
+"Email:" = "E-Mail:";
+"Additional Email:" = "Zusätzliche E-Mail:";
+
+"Phone Number:" = "Telefon:";
+"Prefers to receive messages formatted as:" = "Bevorzugt folgendes Nachrichten-Format:";
+"Screen Name:" = "Messenger-Name:";
+
+"First:" = "Vorname:";
+"Last:" = "Name:";
+"Nickname:" = "Spitzname:";
+
+"Telephone" = "Telefon";
+"Work:" = "Dienstlich:";
+"Home:" = "Privat:";
+"Fax:" = "Fax:";
+"Mobile:" = "Mobil:";
+"Pager:" = "Pager:";
+
+"Title:" = "Titel:";
+"Department:" = "Abteilung:";
+"Organization:" = "Organisation:";
+"Address:" = "Adresse:";
+"City:" = "Stadt:";
+"State_Province:" = "Bundesland:";
+"ZIP_Postal Code:" = "PLZ:";
+"Country:" = "Land:";
+"Web Page:" = "Webseite:";
+
+"Other Infos" = "Andere";
+
+"Note:" = "Notizen:";
+"Timezone:" = "Zeitzone:";
+"Birthday:" = "Geburtsdatum:";
+"Freebusy URL:" = "Free/Busy URL:";
+
+"Add as..." = "Ajouter...";
+"Recipient" = "Destinataire";
+"Carbon Copy" = "Copie carbone";
+"Blind Carbon Copy" = "C. carbone cachée";
+
+"New Addressbook..." = "Neues Adressbuch...";
+"Subscribe to an Addressbook..." = "Abonnieren...";
+"Remove the selected Addressbook" = "Adressbuch löschen";
+
+"Name of the Address Book" = "Adressbuch-Name";
+"Are you sure you want to delete the selected address book?"
+= "Voulez-vous vraiment supprimer le carnet d'adresses sélectionné ?";
+
+"You cannot subscribe to a folder that you own!"
+= "Vous ne pouvez pas vous inscrire à un dossier qui vous appartient!";
+"Unable to subscribe to that folder!"
+= "Impossible de vous inscrire à ce dossier!";
+
+"Default Roles" = "Standard-Rollen";
+"User rights for:" = "Benutzerrechte für:";
+
+"This person can add cards to this addressbook."
+= "Diese Person kann neue Karten zu diesem Adressbuch hinzufügen.";
+"This person can edit the cards of this addressbook."
+= "Diese Person kann in diesem Adressbuch bestehende Karten verändern.";
+"This person can list the content of this addressbook."
+= "Diese Person kann die Liste der Karten dieses Adressbuches anzeigen.";
+"This person can read the cards of this addressbook."
+= "Diese Person kann Karten dieses Adressbuches anzeigen.";
+"This person can erase cards from this addressbook."
+= "Diese Person kann Karten aus diesem Adressbuch löschen";
index 36c2a1ad783013ebde498891aa1cc25912c9d067..ab4ace1c3a0efc9e327708c38b90ccd2b94dd741 100644 (file)
   return 0;
 }
 
-- (NSString *)flatContentAsString {
+- (NSString *) flatContentAsString
+{
   /* Note: we even have the line count in the body-info! */
   NSString *charset;
   NSString *s;
     {
       charset = [[bodyInfo objectForKey:@"parameterList"]
                  objectForKey: @"charset"];
-
-      // TODO: properly decode charset, might need to handle encoding?
-  
-      if ([charset length] > 0)
-       s = [NSString stringWithData: content
-                     usingEncodingNamed: [charset lowercaseString]];
-      else
+      charset = [charset lowercaseString];
+      if (![charset length]
+         || [charset isEqualToString: @"us-ascii"])
        {
          s = [[NSString alloc] initWithData: content
-                               encoding: NSUTF8StringEncoding];
+                               encoding: NSISOLatin1StringEncoding];
          [s autorelease];
        }
+      else
+       {
+         s = [NSString stringWithData: content
+                       usingEncodingNamed: charset];
+         if (![s length])
+           {
+             /* latin 1 is used as a 8bit fallback charset... but does this
+                encoding accept any byte from 0 to 255? */
+             s = [[NSString alloc] initWithData: content
+                                   encoding: NSISOLatin1StringEncoding];
+             [s autorelease];
+           }
+       }
 
       if (!s)
        {
 - (NSString *) pathToAttachmentObject
 {
   /* this points to the SoObject representing the part, no modifications */
-  NSString *url, *n, *pext;
+  NSString *url, *n;
 
   /* path to mail controller object */
   
index 365cab4e3ac3a1088d1a72652397a567e5537e32..f4f041979508939748be44434a7fd7543f8e2bab 100644 (file)
 - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
                            inContext: (WOContext*) context
 {
+  NSString *actionName;
+
+  actionName = [[request requestHandlerPath] lastPathComponent];
+
   return ([[self clientObject] isKindOfClass: [SOGoAppointmentObject class]]
-         && [[request method] isEqualToString: @"POST"]);
+         && [actionName hasPrefix: @"save"]);
 }
 
 - (void) takeValuesFromRequest: (WORequest *) _rq
index d2c2a342c03b0249ba9cb8a4a2a3f6af324ea82e..0258ae2d24ae6adc9256ce416215b66c6589fcd4 100644 (file)
 - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
                            inContext: (WOContext*) context
 {
+  NSString *actionName;
+
+  actionName = [[request requestHandlerPath] lastPathComponent];
+
   return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
-         && [[request method] isEqualToString: @"POST"]);
+         && [actionName hasPrefix: @"save"]);
 }
 
 - (void) takeValuesFromRequest: (WORequest *) _rq
index 10ef59a97759136d7ef8b0ff5e9afba3780d59c0..bacdcb53a534b0e1b9c034becc9c2a40a563c281 100644 (file)
@@ -22,7 +22,6 @@
   </div>
 
   <form const:href="send" name="pageform" enctype="multipart/form-data">
-    <div id="headerArea">
       <div id="attachmentsArea">
        <var:string label:value="Attachments:" />
        <ul id="attachments">
@@ -32,6 +31,7 @@
                /></li></var:foreach>
        </ul>
       </div>
+    <div id="headerArea">
       <span class="headerField"><var:string label:value="From" />:</span>
       <var:popup const:name="from"
        list="fromEMails"
index f70ba607ac109938523d24875ca96ed5b528b032..a610e2332f444ca787a17526c29fe93c92205a83 100644 (file)
@@ -30,16 +30,17 @@ DIV#rightPanel
   overflow: hidden;
 }
 
+/* top list */
 DIV#contactsListContent
-{ position: absolute;
-  background: #fff;
-  width: 100%;
-  height: 16em;
+{ cursor: default;
+  position: absolute;
+  background-color: #fff;
   top: 2.5em;
-  overflow: auto;
-  overflow-x: hidden;
   left: 0px;
-}
+  right: 0px;
+  height: 16em;
+  overflow: hidden;
+  overflow-y: auto; }
 
 .aptview_text
 {
@@ -167,13 +168,9 @@ DIV#folderTreeContent TABLE TD
   padding: 0px; }
 
 TABLE#contactsList
-{ 
-  display: block;
+{ display: block;
   position: relative;
-  color: #000;  
-  background: #fff;
-  width: 100%;
-}
+  width: 100%; }
 
 TABLE#contactsList TD
 { white-space: nowrap;
index 5b0f932f4874ec37947b387fdf9f8d07a2321dc0..9c383e66bfd87f8882b48b5a3f7e896bed1fa3f3 100644 (file)
@@ -45,14 +45,17 @@ DIV#rightPanel
   overflow: hidden;
 }
 
+/* top list */
 DIV#mailboxContent
-{ background-color: #fff;
+{ cursor: default;
   position: absolute;
-  width: 100%;
-  height: 15.5em;
-  left: 0px;
+  background-color: #fff;
   top: 2.5em;
-  right: 0px; }
+  left: 0px;
+  right: 0px;
+  height: 15.5em;
+  overflow: hidden;
+  overflow-y: auto; }
 
 DIV#messageContent
 { position: absolute;
@@ -474,26 +477,9 @@ TABLE#addr_table
 }
 
 TABLE#messageList
-{ cursor: default;
-  display: block;
-  position: absolute;
-  background-color: #fff;
-  color: #000;
-  width: 100%;
-  left: 0px;
-  right: 0px;
-  top: 3.25em;
-  bottom: 1px;
-  overflow: auto;
-  overflow-x: hidden; }
-
-TABLE#messageList THEAD
-{ position: fixed;
-  margin-top: 1px;
-  top: 7.5em;
-  right: 0px;
-  left: 15.5em;
-  height: 2em; }
+{ display: block;
+  position: relative;
+  width: 100%; }
 
 TABLE#messageList TD
 { height: 1.2em; }
index 6eddb0195d960be690b57e1e0e79184fe2b0a304..8bea4af88d31783cc125aa0a4b1b92a1ca54a5f0 100644 (file)
@@ -122,9 +122,9 @@ DIV#rightPanel
   padding: 0px;
   overflow: hidden; }
 
+/* top list */
 DIV#eventsListView
-{ display: block;
-  cursor: default;
+{ cursor: default;
   position: absolute;
   background-color: #fff;
   top: 2.5em;
index a5ceafa4d832e05472a0245485ccb66f29ff342f..0fb99c34fba74fcb3e83427bd1656a2277f77120 100644 (file)
@@ -174,21 +174,22 @@ function closeInvitationWindow() {
 }
 
 function modifyEventCallback(http) {
-   if (http.readyState == 4) {
-      if (http.status == 200) {
-        if (queryParameters["mail-invitation"].toLowerCase() == "yes")
-           closeInvitationWindow();
-        else {
-           window.opener.setTimeout("refreshEventsAndDisplay();", 100);
-           window.setTimeout("window.close();", 100);
-        }
-      }
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      var mailInvitation = queryParameters["mail-invitation"];
+      if (mailInvitation && mailInvitation.toLowerCase() == "yes")
+       closeInvitationWindow();
       else {
-//      log("showing alert...");
-        window.alert(labels["eventPartStatModificationError"]);
+       window.opener.setTimeout("refreshEventsAndDisplay();", 100);
+       window.setTimeout("window.close();", 100);
       }
-      document.modifyEventAjaxRequest = null;
-   }
+    }
+    else {
+//      log("showing alert...");
+      window.alert(labels["eventPartStatModificationError"]);
+    }
+    document.modifyEventAjaxRequest = null;
+  }
 }
 
 function deleteEventCallback(http) {
index e3c227b8d233c8c570e90467d1621dee7c7e86ef..d9cc74eba4cd68bfb0eb995a820c421d6ab49532 100644 (file)
@@ -27,20 +27,22 @@ DIV.addressListElement
 
 SPAN.headerField
 { line-height: 1.8em;
-  width: 5em;
+  width: 7em;
   text-align: right; }
 
 SPAN.headerInput INPUT
-{ width: 100%;
+{ width: 50%;
   padding-left: 24px;
   background-image: url('/SOGo.woa/WebServerResources/abcard.gif');
   background-repeat: no-repeat;
-  background-position: 2px center;
-  margin-right: -12em; }
+  background-position: 2px center; }
+
+DIV#subjectRow
+{ margin-left: 9em; }
 
 DIV#subjectRow INPUT
 { background-image: none;
-  width: 100%;
+  width: 50%;
   padding-left: .5em; }
 
 div#compose_internetmarker
diff --git a/UI/WebServerResources/UIxMailView.js b/UI/WebServerResources/UIxMailView.js
new file mode 100644 (file)
index 0000000..14f04fe
--- /dev/null
@@ -0,0 +1,5 @@
+function onPrintCurrentMessage(event) {
+  window.print();
+
+  preventDefault(event);
+}