From 2934c6bcec3d4aa8bc3be52a37083f522a62c3ec Mon Sep 17 00:00:00 2001 From: wolfgang Date: Fri, 24 Aug 2007 21:33:47 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1155 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 49 +++++++ Scripts/sql-update-20070822.sh | 70 ++++++++++ SoObjects/Appointments/GNUmakefile | 10 +- .../Appointments/SOGoAppointmentFolder.m | 47 ++++++- .../Appointments/SOGoAppointmentObject.m | 4 +- .../SOGoAptMailFrenchDeletion.html | 4 +- .../SOGoAptMailFrenchInvitation.html | 6 +- .../SOGoAptMailFrenchRemoval.html | 4 +- .../SOGoAptMailFrenchUpdate.html | 6 +- .../SOGoAptMailGermanDeletion.html | 4 +- .../SOGoAptMailGermanInvitation.html | 4 +- .../SOGoAptMailGermanRemoval.html | 2 +- .../SOGoAptMailGermanUpdate.html | 6 +- .../Appointments/SOGoAptMailNotification.h | 16 +-- .../Appointments/SOGoAptMailNotification.m | 5 +- SoObjects/Contacts/SOGoContactFolders.m | 23 ---- SoObjects/Mailer/SOGoDraftObject.m | 31 +---- SoObjects/Mailer/SOGoMailFolder.m | 49 ++----- SoObjects/Mailer/bundle-info.plist | 2 + SoObjects/SOGo/NSString+Utilities.h | 2 + SoObjects/SOGo/NSString+Utilities.m | 20 +++ SoObjects/SOGo/SOGoFolder.m | 3 +- SoObjects/SOGo/SOGoUserFolder.m | 2 +- UI/Contacts/German.lproj/Localizable.strings | 129 ++++++++++++++++++ UI/MailPartViewers/UIxMailPartViewer.m | 30 ++-- UI/Scheduler/UIxAppointmentEditor.m | 6 +- UI/Scheduler/UIxTaskEditor.m | 6 +- UI/Templates/MailerUI/UIxMailEditor.wox | 2 +- UI/WebServerResources/ContactsUI.css | 23 ++-- UI/WebServerResources/MailerUI.css | 36 ++--- UI/WebServerResources/SchedulerUI.css | 4 +- UI/WebServerResources/SchedulerUI.js | 27 ++-- UI/WebServerResources/UIxMailEditor.css | 12 +- UI/WebServerResources/UIxMailView.js | 5 + 34 files changed, 451 insertions(+), 198 deletions(-) create mode 100755 Scripts/sql-update-20070822.sh create mode 100644 SoObjects/Mailer/bundle-info.plist create mode 100644 UI/Contacts/German.lproj/Localizable.strings create mode 100644 UI/WebServerResources/UIxMailView.js diff --git a/ChangeLog b/ChangeLog index 0bcd7abe..6c30d788 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2007-08-24 Wolfgang Sourdeau + + * 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 + + * 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 * UI/PreferencesUI/UIxPreferences.m ([UIxPreferences diff --git a/Scripts/sql-update-20070822.sh b/Scripts/sql-update-20070822.sh new file mode 100755 index 00000000..80a41a2b --- /dev/null +++ b/Scripts/sql-update-20070822.sh @@ -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 diff --git a/SoObjects/Appointments/GNUmakefile b/SoObjects/Appointments/GNUmakefile index 4e3d3255..789501a3 100644 --- a/SoObjects/Appointments/GNUmakefile +++ b/SoObjects/Appointments/GNUmakefile @@ -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 diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 5e7955a7..9fa1695f 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -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 */ diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 9b1b334f..1058df10 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -106,7 +106,9 @@ /* 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; diff --git a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html index 38d29abb..78072651 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html @@ -1,4 +1,4 @@ -<#IsSubject>Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé +<#IsSubject>Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé <#IsBody> -Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé par <#Organizer />. +Le rendez-vous du <#AptStartDate /> à <#AptStartTime /> a été supprimé par <#Organizer />. diff --git a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html index 271a375c..b3313946 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html @@ -1,7 +1,7 @@ -<#IsSubject>Rendez-vous le <#AptStartDate /> à <#AptStartTime /> +<#IsSubject>Rendez-vous le <#AptStartDate /> à <#AptStartTime /> <#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 />. diff --git a/SoObjects/Appointments/SOGoAptMailFrenchRemoval.wo/SOGoAptMailFrenchRemoval.html b/SoObjects/Appointments/SOGoAptMailFrenchRemoval.wo/SOGoAptMailFrenchRemoval.html index bbe73df3..1cf438f7 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchRemoval.wo/SOGoAptMailFrenchRemoval.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchRemoval.wo/SOGoAptMailFrenchRemoval.html @@ -1,4 +1,4 @@ -<#IsSubject>Supprimé de la réunion du <#AptStartDate /> à <#AptStartTime /> +<#IsSubject>Supprimé de la réunion du <#AptStartDate /> à <#AptStartTime /> <#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 />. diff --git a/SoObjects/Appointments/SOGoAptMailFrenchUpdate.wo/SOGoAptMailFrenchUpdate.html b/SoObjects/Appointments/SOGoAptMailFrenchUpdate.wo/SOGoAptMailFrenchUpdate.html index 901e34e1..c008d380 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchUpdate.wo/SOGoAptMailFrenchUpdate.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchUpdate.wo/SOGoAptMailFrenchUpdate.html @@ -1,5 +1,5 @@ -<#IsSubject>Rendez-vous du <#OldAptStartDate /> à <#OldAptStartTime /> modifié +<#IsSubject>Rendez-vous du <#OldAptStartDate /> à <#OldAptStartTime /> modifié <#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 />. diff --git a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html index 5653d744..edbc3088 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html @@ -1,4 +1,4 @@ -<#IsSubject>Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde gelöscht. +<#IsSubject>Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde gelöscht. <#IsBody> -Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde von <#Organizer /> gelöscht. +Der Termin am <#AptStartDate /> um <#AptStartTime /> wurde von <#Organizer /> gelöscht. diff --git a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html index 982c66a1..383fbb85 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html @@ -1,7 +1,7 @@ <#IsSubject>Termin am <#AptStartDate /> um <#AptStartTime /> <#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 />. diff --git a/SoObjects/Appointments/SOGoAptMailGermanRemoval.wo/SOGoAptMailGermanRemoval.html b/SoObjects/Appointments/SOGoAptMailGermanRemoval.wo/SOGoAptMailGermanRemoval.html index 3133ccc6..3261311e 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanRemoval.wo/SOGoAptMailGermanRemoval.html +++ b/SoObjects/Appointments/SOGoAptMailGermanRemoval.wo/SOGoAptMailGermanRemoval.html @@ -1,4 +1,4 @@ -<#IsSubject>Von dem Termin am <#AptStartDate /> um <#AptStartTime /> gelöscht +<#IsSubject>Von dem Termin am <#AptStartDate /> um <#AptStartTime /> gelöscht <#IsBody> Sie sind nicht mehr eingeladen zu dem Termin am <#AptStartDate /> um <#AptStartTime /> organisiert von <#Organizer />. diff --git a/SoObjects/Appointments/SOGoAptMailGermanUpdate.wo/SOGoAptMailGermanUpdate.html b/SoObjects/Appointments/SOGoAptMailGermanUpdate.wo/SOGoAptMailGermanUpdate.html index b0fd4dc9..f5ce3667 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanUpdate.wo/SOGoAptMailGermanUpdate.html +++ b/SoObjects/Appointments/SOGoAptMailGermanUpdate.wo/SOGoAptMailGermanUpdate.html @@ -1,5 +1,5 @@ -<#IsSubject>Veränderung des Termins am <#OldAptStartDate /> um <#OldAptStartTime /> +<#IsSubject>Veränderung des Termins am <#OldAptStartDate /> um <#OldAptStartTime /> <#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 />. diff --git a/SoObjects/Appointments/SOGoAptMailNotification.h b/SoObjects/Appointments/SOGoAptMailNotification.h index 93457175..ba774b18 100644 --- a/SoObjects/Appointments/SOGoAptMailNotification.h +++ b/SoObjects/Appointments/SOGoAptMailNotification.h @@ -48,21 +48,21 @@ - (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 diff --git a/SoObjects/Appointments/SOGoAptMailNotification.m b/SoObjects/Appointments/SOGoAptMailNotification.m index 788669af..5c6b2c4f 100644 --- a/SoObjects/Appointments/SOGoAptMailNotification.m +++ b/SoObjects/Appointments/SOGoAptMailNotification.m @@ -28,6 +28,8 @@ #import #import +#import + #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 { diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m index f166515a..21587097 100644 --- a/SoObjects/Contacts/SOGoContactFolders.m +++ b/SoObjects/Contacts/SOGoContactFolders.m @@ -240,29 +240,6 @@ 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; diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 6c49beb9..a8a63135 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -53,6 +53,7 @@ #import #import +#import #import #import #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; diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 7087a171..babd5684 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -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 index 00000000..2c63c085 --- /dev/null +++ b/SoObjects/Mailer/bundle-info.plist @@ -0,0 +1,2 @@ +{ +} diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h index 7cd8042b..0f2e95a9 100644 --- a/SoObjects/SOGo/NSString+Utilities.h +++ b/SoObjects/SOGo/NSString+Utilities.h @@ -46,6 +46,8 @@ /* bare email addresses */ - (NSString *) pureEMailAddress; +- (NSString *) asQPSubjectString: (NSString *) encoding; + #ifndef GNUSTEP_BASE_LIBRARY - (BOOL) boolValue; #endif diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 38c09bad..bb8ece23 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -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 { diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index d6676c0e..20a3b894 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -42,6 +42,7 @@ #import #import +#import "NSArray+Utilities.h" #import "NSString+Utilities.h" #import "SOGoPermissions.h" @@ -211,7 +212,7 @@ static NSString *defaultUserID = @""; } if ([records isKindOfClass: [NSException class]]) return records; - return [records valueForKey: @"c_name"]; + return [records objectsForKey: @"c_name"]; } - (BOOL) nameExistsInFolder: (NSString *) objectName diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index 933779c3..8db12b30 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -101,7 +101,7 @@ - (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 index 00000000..9f4500ab --- /dev/null +++ b/UI/Contacts/German.lproj/Localizable.strings @@ -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"; diff --git a/UI/MailPartViewers/UIxMailPartViewer.m b/UI/MailPartViewers/UIxMailPartViewer.m index 36c2a1ad..ab4ace1c 100644 --- a/UI/MailPartViewers/UIxMailPartViewer.m +++ b/UI/MailPartViewers/UIxMailPartViewer.m @@ -164,7 +164,8 @@ return 0; } -- (NSString *)flatContentAsString { +- (NSString *) flatContentAsString +{ /* Note: we even have the line count in the body-info! */ NSString *charset; NSString *s; @@ -175,18 +176,27 @@ { 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) { @@ -302,7 +312,7 @@ - (NSString *) pathToAttachmentObject { /* this points to the SoObject representing the part, no modifications */ - NSString *url, *n, *pext; + NSString *url, *n; /* path to mail controller object */ diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 365cab4e..f4f04197 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -319,8 +319,12 @@ - (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 diff --git a/UI/Scheduler/UIxTaskEditor.m b/UI/Scheduler/UIxTaskEditor.m index d2c2a342..0258ae2d 100644 --- a/UI/Scheduler/UIxTaskEditor.m +++ b/UI/Scheduler/UIxTaskEditor.m @@ -357,8 +357,12 @@ - (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 diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index 10ef59a9..bacdcb53 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -22,7 +22,6 @@
-
    @@ -32,6 +31,7 @@ />
+
: