]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1025 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Thu, 15 Feb 2007 21:16:35 +0000 (21:16 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Thu, 15 Feb 2007 21:16:35 +0000 (21:16 +0000)
29 files changed:
ChangeLog
SOPE/NGCards/CardGroup.h
SOPE/NGCards/CardGroup.m
SOPE/NGCards/ChangeLog
SoObjects/Appointments/SOGoAppointmentObject.h
SoObjects/Appointments/SOGoAppointmentObject.m
SoObjects/Appointments/SOGoCalendarComponent.h
SoObjects/Appointments/SOGoCalendarComponent.m
SoObjects/Appointments/SOGoTaskObject.h
SoObjects/Appointments/SOGoTaskObject.m
SoObjects/Appointments/product.plist
SoObjects/Mailer/SOGoMailObject.m
SoObjects/SOGo/SOGoPermissions.h
SoObjects/SOGo/SOGoPermissions.m
UI/MailPartViewers/French.lproj/Localizable.strings
UI/MailPartViewers/GNUmakefile
UI/MailPartViewers/UIxMailPartAlternativeViewer.m
UI/MailPartViewers/UIxMailPartHTMLViewer.m
UI/MailPartViewers/UIxMailPartICalViewer.m
UI/MailPartViewers/UIxMailPartViewer.m
UI/MailPartViewers/UIxMailRenderingContext.m
UI/Scheduler/UIxAppointmentEditor.m
UI/Scheduler/UIxAppointmentView.m
UI/Scheduler/UIxComponentEditor.m
UI/Scheduler/UIxTaskEditor.m
UI/Scheduler/UIxTaskView.m
UI/Scheduler/product.plist
UI/Templates/MailPartViewers/UIxMailPartHTMLViewer.wox
UI/WebServerResources/MailerUI.css

index 90bbbff2daeed5e12dd72b3211954cf64413b3da..832b7b0601bd51ed4f9159705659c59c5af99b38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2007-02-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailPartViewers/UIxMailRenderingContext.m: returns the
+       alternativeViewer a multipart/related message is being handled.
+
+       * UI/MailPartViewers/UIxMailPartHTMLViewer.m: reimplemented module
+       from scratch.
+
+       * UI/MailPartViewers/UIxMailPartAlternativeViewer.m: select the
+       text/html component before text/plain.
+
+       * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
+       -addRequiredKeysOfStructure:path:toArray:recurse:]): accepts the
+       fetching of HTML parts.
+
+       * SoObjects/Appointments/SOGoCalendarComponent.m
+       ([SOGoCalendarComponent -componentTag]): new template method that
+       returns the vcalendar tag of the current object.
+       ([SOGoCalendarComponent -component]): new method that returns the
+       first object matching [self componentTag] within the current
+       calendar object. This method replaces 'firstEventInCalendar:' as
+       well as "firstTaskInCalendar:".
+       ([SOGoCalendarComponent -roleOfUser:logininContext:context]):
+       moved method from SOGoAppointmentObject.m.
+
 2007-02-13  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/Scheduler/UIxCalMulticolumnDayView.[hm]: new daily view
 2007-02-13  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/Scheduler/UIxCalMulticolumnDayView.[hm]: new daily view
index 3108f8b937ac4d1fe8406870f9f336d842806df7..6800f07693eff300c1832010069f9c9014ff1477 100644 (file)
@@ -50,6 +50,7 @@
 - (void) addChildren: (NSArray *) someChildren;
 
 - (NSArray *) children;
 - (void) addChildren: (NSArray *) someChildren;
 
 - (NSArray *) children;
+- (CardElement *) firstChildWithTag: (NSString *) aTag;
 - (NSArray *) childrenWithTag: (NSString *) aTag;
 - (NSArray *) childrenWithAttribute: (NSString *) anAttribute
                         havingValue: (NSString *) aValue;
 - (NSArray *) childrenWithTag: (NSString *) aTag;
 - (NSArray *) childrenWithAttribute: (NSString *) anAttribute
                         havingValue: (NSString *) aValue;
@@ -64,7 +65,6 @@
                    types: (NSArray *) someTypes
              singleValue: (NSString *) aValue;
 
                    types: (NSArray *) someTypes
              singleValue: (NSString *) aValue;
 
-
 - (CardGroup *) groupWithClass: (Class) groupClass;
 - (void) setChildrenAsCopy: (NSMutableArray *) someChildren;
 
 - (CardGroup *) groupWithClass: (Class) groupClass;
 - (void) setChildrenAsCopy: (NSMutableArray *) someChildren;
 
index b7b60ca7118c4cdca638de4b8ff2bfe606617943..ae375d46b550eb568204f3119eeafde3cdfad7d4 100644 (file)
@@ -232,6 +232,33 @@ static NGCardsSaxHandler *sax = nil;
   [self addChild: aChild];
 }
 
   [self addChild: aChild];
 }
 
+- (CardElement *) firstChildWithTag: (NSString *) aTag;
+{
+  Class mappedClass;
+  CardElement *child, *mappedChild;
+  NSArray *existing;
+
+  existing = [self childrenWithTag: aTag];
+  if ([existing count])
+    {
+      child = [existing objectAtIndex: 0];
+      mappedClass = [self classForTag: [aTag uppercaseString]];
+      if (mappedClass)
+        {
+          if ([child isKindOfClass: [CardGroup class]])
+            mappedChild = [(CardGroup *) child groupWithClass: mappedClass];
+          else
+            mappedChild = [child elementWithClass: mappedClass];
+        }
+      else
+        mappedChild = child;
+    }
+  else
+    mappedChild = nil;
+
+  return mappedChild;
+}
+
 - (void) addChildren: (NSArray *) someChildren
 {
   CardElement *currentChild;
 - (void) addChildren: (NSArray *) someChildren
 {
   CardElement *currentChild;
index e5dea66158efee885650290e4d3e6da8d7067532..6b01b6497673a4e879ba3e572e5a7f8f6fe82537 100644 (file)
@@ -1,3 +1,7 @@
+2007-02-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * CardGroup.m ([CardGroup -firstChildWithTag:aTag]): new method.
+
 2007-02-09  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * CardGroup.m ([CardGroup +cardParser]): find the correct parser
 2007-02-09  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * CardGroup.m ([CardGroup +cardParser]): find the correct parser
index ab41219b59c57e98fdc889360878456fa25ab0fb..17e9b24b0d179dd0cbfdff61252f4c2f16c5b8c2 100644 (file)
 
 @interface SOGoAppointmentObject : SOGoCalendarComponent
 
 
 @interface SOGoAppointmentObject : SOGoCalendarComponent
 
-/* accessors */
-
-- (iCalEvent *) event;
-- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) calendar;
-
 /* folder management */
 
 - (id) lookupHomeFolderForUID: (NSString *) _uid inContext: (id)_ctx;
 /* folder management */
 
 - (id) lookupHomeFolderForUID: (NSString *) _uid inContext: (id)_ctx;
index e9c9b73f59386f5180ac8e83ff65373f0d0afea1..b2b8e1f97adf2f5f33ac97e96dd0535b04d929e5 100644 (file)
@@ -28,6 +28,7 @@
 
 #import <SOGo/AgenorUserManager.h>
 #import <SOGo/SOGoObject.h>
 
 #import <SOGo/AgenorUserManager.h>
 #import <SOGo/SOGoObject.h>
+#import <SOGo/SOGoPermissions.h>
 
 #import "iCalEntityObject+Agenor.h"
 
 
 #import "iCalEntityObject+Agenor.h"
 
 
 @implementation SOGoAppointmentObject
 
 
 @implementation SOGoAppointmentObject
 
-/* accessors */
-
-- (iCalEvent *) event
+- (NSString *) componentTag
 {
 {
-  return [self firstEventFromCalendar: [self calendar]];
+  return @"vevent";
 }
 
 /* iCal handling */
 }
 
 /* iCal handling */
 
   /* add attendees */
   
 
   /* add attendees */
   
-  for (i = 0; i < count; i++) {
-    iCalPerson *person;
+  for (i = 0; i < count; i++)
+    {
+      iCalPerson *person;
     
     
-    person = [attendees objectAtIndex:i];
-    email  = [person rfc822Email];
-    if (![email isNotNull]) continue;
+      person = [attendees objectAtIndex:i];
+      email  = [person rfc822Email];
+      if (![email isNotNull]) continue;
     
     
-    uid = [um getUIDForEmail:email];
-    if (![uid isNotNull]) {
-      [self logWithFormat:@"Note: got no uid for email: '%@'", email];
-      continue;
+      uid = [um getUIDForEmail:email];
+      if (![uid isNotNull]) {
+        [self logWithFormat:@"Note: got no uid for email: '%@'", email];
+        continue;
+      }
+      if (![uids containsObject:uid])
+        [uids addObject:uid];
     }
     }
-    if (![uids containsObject:uid])
-      [uids addObject:uid];
-  }
-  
+
   return uids;
 }
 
   return uids;
 }
 
   return allErrors;
 }
 
   return allErrors;
 }
 
-- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) aCalendar
-{
-  iCalEvent *event;
-  NSArray *events;
-
-  events = [aCalendar childrenWithTag: @"vevent"];
-  if ([events count])
-    event = (iCalEvent *) [[events objectAtIndex: 0]
-                            groupWithClass: [iCalEvent class]];
-  else
-    event = nil;
-
-  return event;
-}
-
 /* "iCal multifolder saves" */
 
 - (NSException *) saveContentString: (NSString *) _iCal
 /* "iCal multifolder saves" */
 
 - (NSException *) saveContentString: (NSString *) _iCal
       oldApt = nil;
     }
   else
       oldApt = nil;
     }
   else
-    oldApt = [self firstEventFromCalendar: [self calendar]];
+    oldApt = (iCalEvent *) [self component];
   
   /* compare sequence if requested */
 
   
   /* compare sequence if requested */
 
   /* handle new content */
   
   newCalendar = [iCalCalendar parseSingleFromSource: _iCal];
   /* handle new content */
   
   newCalendar = [iCalCalendar parseSingleFromSource: _iCal];
-  newApt = [self firstEventFromCalendar: newCalendar];
+  newApt = (iCalEvent *) [newCalendar firstChildWithTag: [self componentTag]];
   if (newApt == nil) {
     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
                        reason:@"could not parse iCalendar content!"];
   if (newApt == nil) {
     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
                        reason:@"could not parse iCalendar content!"];
 
   /* load existing content */
 
 
   /* load existing content */
 
-  apt = [self event];  
+  apt = (iCalEvent *) [self component];
   
   /* compare sequence if requested */
 
   
   /* compare sequence if requested */
 
   ex = nil;
 
   // TODO: do we need to use SOGoAppointment? (prefer iCalEvent?)
   ex = nil;
 
   // TODO: do we need to use SOGoAppointment? (prefer iCalEvent?)
-  apt = [self event];
+  apt = (iCalEvent *) [self component];
 
   if (apt)
     {
 
   if (apt)
     {
   else
     {
       eventCalendar = [iCalCalendar parseSingleFromSource: contentString];
   else
     {
       eventCalendar = [iCalCalendar parseSingleFromSource: contentString];
-      event = [self firstEventFromCalendar: eventCalendar];
+      event = (iCalEvent *) [eventCalendar firstChildWithTag: [self componentTag]];
       organizers = [event childrenWithTag: @"organizer"];
       if ([organizers count])
         newContentString = contentString;
       organizers = [event childrenWithTag: @"organizer"];
       if ([organizers count])
         newContentString = contentString;
                 baseVersion: baseVersion];
 }
 
                 baseVersion: baseVersion];
 }
 
-- (NSString *) roleOfUser: (NSString *) login
-                inContext: (WOContext *) context
-{
-  AgenorUserManager *um;
-  iCalEvent *event;
-  NSString *role, *email;
-
-  um = [AgenorUserManager sharedUserManager];
-  email = [um getEmailForUID: login];
-
-  event = [self event];
-  if ([event isOrganizer: email])
-    role = @"Organizer";
-  else if ([event isParticipant: email])
-    role = @"Participant";
-  else if ([[[self container] ownerInContext: nil] isEqualToString: login])
-    role = @"SoRole_Owner";
-  else
-    role = nil;
-
-  return role;
-}
-
 @end /* SOGoAppointmentObject */
 
 
 @end /* SOGoAppointmentObject */
 
 
index 101ebbb43133055f78a3be81a5cbf0e40504397e..50e069ee5334d20d52b0dfff7d63bfd6d2686062 100644 (file)
@@ -36,9 +36,9 @@
   iCalCalendar *calendar;
 }
 
   iCalCalendar *calendar;
 }
 
-/* accessors */
-
+- (NSString *) componentTag;
 - (iCalCalendar *) calendar;
 - (iCalCalendar *) calendar;
+- (iCalRepeatableEntityObject *) component;
 
 - (NSException *) primarySaveContentString: (NSString *) _iCalString;
 - (NSException *) primaryDelete;
 
 - (NSException *) primarySaveContentString: (NSString *) _iCalString;
 - (NSException *) primaryDelete;
index ffae08c17d25a3cc3e553b3af687976166855819..6ebce383b029d9f9c2a8b8c6ccd1a870a898757b 100644 (file)
@@ -30,6 +30,7 @@
 #import <NGMail/NGSendMail.h>
 
 #import <SOGo/AgenorUserManager.h>
 #import <NGMail/NGSendMail.h>
 
 #import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoPermissions.h>
 
 #import "common.h"
 
 
 #import "common.h"
 
@@ -83,6 +84,13 @@ static BOOL sendEMailNotifications = NO;
   return @"text/calendar";
 }
 
   return @"text/calendar";
 }
 
+- (NSString *) componentTag
+{
+  [self subclassResponsibility: _cmd];
+
+  return nil;
+}
+
 - (iCalCalendar *) calendar
 {
   NSString *iCalString;
 - (iCalCalendar *) calendar
 {
   NSString *iCalString;
@@ -100,6 +108,13 @@ static BOOL sendEMailNotifications = NO;
   return calendar;
 }
 
   return calendar;
 }
 
+- (iCalRepeatableEntityObject *) component
+{
+  return (iCalRepeatableEntityObject *)
+    [[self calendar]
+      firstChildWithTag: [self componentTag]];
+}
+
 /* raw saving */
 
 - (NSException *) primarySaveContentString: (NSString *) _iCalString
 /* raw saving */
 
 - (NSException *) primarySaveContentString: (NSString *) _iCalString
@@ -229,7 +244,7 @@ static BOOL sendEMailNotifications = NO;
 
           /* construct message */
           headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
 
           /* construct message */
           headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
-    
+          
           /* NOTE: multipart/alternative seems like the correct choice but
            * unfortunately Thunderbird doesn't offer the rich content alternative
            * at all. Mail.app shows the rich content alternative _only_
           /* NOTE: multipart/alternative seems like the correct choice but
            * unfortunately Thunderbird doesn't offer the rich content alternative
            * at all. Mail.app shows the rich content alternative _only_
@@ -279,4 +294,27 @@ static BOOL sendEMailNotifications = NO;
     }
 }
 
     }
 }
 
+- (NSString *) roleOfUser: (NSString *) login
+                inContext: (WOContext *) context
+{
+  AgenorUserManager *um;
+  iCalRepeatableEntityObject *component;
+  NSString *role, *email;
+
+  um = [AgenorUserManager sharedUserManager];
+  email = [um getEmailForUID: login];
+
+  component = [self component];
+  if ([component isOrganizer: email])
+    role = SOGoRole_Organizer;
+  else if ([component isParticipant: email])
+    role = SOGoRole_Participant;
+  else if ([[[self container] ownerInContext: nil] isEqualToString: login])
+    role = SoRole_Owner;
+  else
+    role = nil;
+
+  return role;
+}
+
 @end
 @end
index d0603786588aa6e3250e8bcc7406bb7f9fed93a1..23436263330221ce32cef979ccacebf40594392f 100644 (file)
 
 @interface SOGoTaskObject : SOGoCalendarComponent
 
 
 @interface SOGoTaskObject : SOGoCalendarComponent
 
-/* accessors */
-
-- (iCalToDo *) task;
-- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) calendar;
-
 /* folder management */
 
 - (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx;
 /* folder management */
 
 - (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx;
index 775dcecf7205c002a2068a3c17c02eef37f06bf7..a70cf10eb7256aaeda57d44cfc8b361f577e933c 100644 (file)
@@ -58,11 +58,9 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     mailTemplateDefaultLanguage = @"French";
 }
 
     mailTemplateDefaultLanguage = @"French";
 }
 
-/* accessors */
-
-- (iCalToDo *) task
+- (NSString *) componentTag
 {
 {
-  return [self firstTaskFromCalendar: [self calendar]];
+  return @"vtodo";
 }
 
 /* iCal handling */
 }
 
 /* iCal handling */
@@ -206,21 +204,6 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   return allErrors;
 }
 
   return allErrors;
 }
 
-- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) aCalendar
-{
-  iCalToDo *task;
-  NSArray *tasks;
-
-  tasks = [aCalendar childrenWithTag: @"vtodo"];
-  if ([tasks count])
-    task = (iCalToDo *) [[tasks objectAtIndex: 0]
-                           groupWithClass: [iCalToDo class]];
-  else
-    task = nil;
-
-  return task;
-}
-
 /* "iCal multifolder saves" */
 
 - (NSException *) saveContentString: (NSString *) _iCal
 /* "iCal multifolder saves" */
 
 - (NSException *) saveContentString: (NSString *) _iCal
@@ -430,7 +413,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
 
   /* load existing content */
   
 
   /* load existing content */
   
-  task = [self task];
+  task = (iCalToDo *) [self component];
   
   /* compare sequence if requested */
 
   
   /* compare sequence if requested */
 
@@ -479,7 +462,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   NSString        *myEMail;
   
   // TODO: do we need to use SOGoTask? (prefer iCalToDo?)
   NSString        *myEMail;
   
   // TODO: do we need to use SOGoTask? (prefer iCalToDo?)
-  task = [self task];
+  task = (iCalToDo *) [self component];
 
   if (task == nil) {
     return [NSException exceptionWithHTTPStatus:500 /* Server Error */
 
   if (task == nil) {
     return [NSException exceptionWithHTTPStatus:500 /* Server Error */
index bb2f1a8187df08a6d45a5f32eb04ce8b6f35dc51..a648d70a41c0827824777ba55f452bd5321f4a1b 100644 (file)
       superclass    = "SOGoContentObject";
       defaultRoles = {
         "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
       superclass    = "SOGoContentObject";
       defaultRoles = {
         "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
+        "Change Images and Files" = ( "Owner", "Delegate", "Organizer" );
       };
     };
       };
     };
-
     SOGoTaskObject = {
       superclass    = "SOGoContentObject";
       defaultRoles = {
         "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
     SOGoTaskObject = {
       superclass    = "SOGoContentObject";
       defaultRoles = {
         "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
+        "Change Images and Files" = ( "Owner", "Delegate", "Organizer" );
       };
     };
     SOGoFreeBusyObject = {
       };
     };
     SOGoFreeBusyObject = {
index 4b30424b0cd0b2ab732964d93b1b2aa6ef562203..10d848cf1067079d3c7f75ba487a6bc32c532969 100644 (file)
@@ -418,7 +418,8 @@ static BOOL debugSoParts       = NO;
   _subtype = [_subtype lowercaseString];
   
   if ([_type isEqualToString:@"text"]) {
   _subtype = [_subtype lowercaseString];
   
   if ([_type isEqualToString:@"text"]) {
-    if ([_subtype isEqualToString:@"plain"])
+    if ([_subtype isEqualToString:@"plain"]
+        || [_subtype isEqualToString:@"html"])
       return YES;
 
     if ([_subtype isEqualToString:@"calendar"]) /* we also fetch calendars */
       return YES;
 
     if ([_subtype isEqualToString:@"calendar"]) /* we also fetch calendars */
index ee196174a2f387df4a2ad7c1c9f6c7d83bfb2390..5f0e51cce779e6fad56d50daaeb98dff91a5b2ea 100644 (file)
@@ -36,4 +36,7 @@ extern NSString *SOGoPerm_ReadAcls;
 extern NSString *SOGoPerm_CreateAndModifyAcls;
 extern NSString *SOGoPerm_FreeBusyLookup;
 
 extern NSString *SOGoPerm_CreateAndModifyAcls;
 extern NSString *SOGoPerm_FreeBusyLookup;
 
+extern NSString *SOGoRole_Organizer;
+extern NSString *SOGoRole_Participant;
+
 #endif /* SOGOPERMISSIONS_H */
 #endif /* SOGOPERMISSIONS_H */
index 13e7cb9c6d4069c6b64ec1d1842625ba5385f519..1b856bb26d0d8b78ff108d35fc2165e1f04d23e5 100644 (file)
@@ -34,6 +34,10 @@ NSString *SOGoRole_FreeBusyLookup = @"FreeBusyLookup"; /* for users that have
 NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user
                                             */
 
 NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user
                                             */
 
+/* Calendar */
+NSString *SOGoRole_Organizer = @"Organizer";
+NSString *SOGoRole_Participant = @"Participant";
+
 #warning ReadAcls still not used...
 NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in
                                               the WebDAV acls spec, which is
 #warning ReadAcls still not used...
 NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in
                                               the WebDAV acls spec, which is
index d7cacae22c86bf42fcb0db4d54a2128e9c7b03f5..6b90b000947a4782675a94b94805096c209b83f6 100644 (file)
@@ -25,3 +25,5 @@ do_tentative        = "tentative";
 do_update_status    = "mettre l'agenda Ã  jour";
 reply_info_no_attendee = "Vous avez reçu une réponse Ã  un Ã©vénement mais l'expéditeur n'est pas un invité.";
 reply_info          = "Ceci est une réponse Ã  un Ã©vénement que vous avez organisé.";
 do_update_status    = "mettre l'agenda Ã  jour";
 reply_info_no_attendee = "Vous avez reçu une réponse Ã  un Ã©vénement mais l'expéditeur n'est pas un invité.";
 reply_info          = "Ceci est une réponse Ã  un Ã©vénement que vous avez organisé.";
+
+"Size" = "Taille";
index 44e1aeed2e7b7d97eebcd2bc57d04c2df259fa61..1850ca57d651d514e54c6d71f6c7b4ddc8a4ec78 100644 (file)
@@ -18,13 +18,13 @@ MailPartViewers_OBJC_FILES += \
        \
        UIxMailPartViewer.m             \
        UIxMailPartTextViewer.m         \
        \
        UIxMailPartViewer.m             \
        UIxMailPartTextViewer.m         \
+       UIxMailPartHTMLViewer.m         \
        UIxMailPartImageViewer.m        \
        UIxMailPartLinkViewer.m         \
        UIxMailPartMixedViewer.m        \
        UIxMailPartAlternativeViewer.m  \
        UIxMailPartMessageViewer.m      \
        UIxMailPartICalViewer.m         \
        UIxMailPartImageViewer.m        \
        UIxMailPartLinkViewer.m         \
        UIxMailPartMixedViewer.m        \
        UIxMailPartAlternativeViewer.m  \
        UIxMailPartMessageViewer.m      \
        UIxMailPartICalViewer.m         \
-       UIxMailPartHTMLViewer.m         \
        \
        UIxMailPartICalAction.m         \
        \
        \
        UIxMailPartICalAction.m         \
        \
index 95e4e2e7a6cfdd103d951746753858eed3068966..e7ff28aa1f2680aa9d9643ef0ee0ccfd8e562c60 100644 (file)
   if ((count = [_types count]) == 0)
     return NSNotFound;
   
   if ((count = [_types count]) == 0)
     return NSNotFound;
   
-  /* we always choose text/plain if available */
+  if ((i = [_types indexOfObject:@"text/html"]) != NSNotFound)
+    return i;
   if ((i = [_types indexOfObject:@"text/plain"]) != NSNotFound)
     return i;
   if ((i = [_types indexOfObject:@"text/plain"]) != NSNotFound)
     return i;
-  
+
   /* then we scan for other text types and choose the first one found */
   for (i = 0; i < count; i++) {
     if ([(NSString *)[_types objectAtIndex:i] hasPrefix:@"text/"])
   /* then we scan for other text types and choose the first one found */
   for (i = 0; i < count; i++) {
     if ([(NSString *)[_types objectAtIndex:i] hasPrefix:@"text/"])
index ab7746de634b2d007a3f7d93dca90f8138e604eb..4b926e1e18ec1f35eaee1521fd59fbe23819834c 100644 (file)
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
+/* UIxMailPartHTMLViewer.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
 
-  This file is part of OpenGroupware.org.
+#import <Foundation/NSArray.h>
+#import <SaxObjC/SaxAttributes.h>
+#import <SaxObjC/SaxContentHandler.h>
+#import <SaxObjC/SaxLexicalHandler.h>
+#import <SaxObjC/SaxXMLReader.h>
+#import <SaxObjC/SaxXMLReaderFactory.h>
+#import <NGExtensions/NSString+misc.h>
+#import <NGObjWeb/SoObjects.h>
 
 
-  OGo 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, or (at your option) any
-  later version.
+#import "UIxMailPartHTMLViewer.h"
 
 
-  OGo 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.
+#define showWhoWeAre() NSLog(@"invoked '%@'", NSStringFromSelector(_cmd))
 
 
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
+@interface _UIxHTMLMailContentHandler : NSObject <SaxContentHandler, SaxLexicalHandler>
+{
+  NSMutableString *result;
+  NSMutableString *css;
+  NSDictionary *attachmentIds;
+  BOOL inBody;
+  BOOL inStyle;
+  BOOL inScript;
+  BOOL inCSSDeclaration;
+  NSMutableArray *crumb;
+}
 
 
-#include "UIxMailPartLinkViewer.h"
+- (NSString *) result;
 
 
-@interface UIxMailPartHTMLViewer : UIxMailPartLinkViewer
 @end
 
 @end
 
-#include "common.h"
+@implementation _UIxHTMLMailContentHandler
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      crumb = nil;
+      css = nil;
+      result = nil;
+      attachmentIds = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (crumb)
+    [crumb release];
+  if (result)
+    [result release];
+  if (css)
+    [css release];
+  [super dealloc];
+}
+
+- (void) setAttachmentIds: (NSDictionary *) newAttachmentIds
+{
+  attachmentIds = newAttachmentIds;
+}
+
+- (NSString *) css
+{
+  return [[css copy] autorelease];
+}
+
+- (NSString *) result
+{
+  return [[result copy] autorelease];
+}
+
+/* SaxContentHandler */
+- (void) startDocument
+{
+  if (crumb)
+    [crumb release];
+  if (result)
+    [result release];
+  if (css)
+    [css release];
+
+  result = [NSMutableString new];
+  css = [NSMutableString new];
+  crumb = [NSMutableArray new];
+  inBody = NO;
+  inStyle = NO;
+  inScript = NO;
+  inCSSDeclaration = NO;
+}
+
+- (void) endDocument
+{
+  unsigned int count, max;
+
+  max = [crumb count];
+  if (max > 0)
+    for (count = max - 1; count > -1; count--)
+      {
+        [result appendFormat: @"</%@>", [crumb objectAtIndex: count]];
+        [crumb removeObjectAtIndex: count];
+      }
+}
+
+- (void) startPrefixMapping: (NSString *)_prefix
+                        uri: (NSString *)_uri
+{
+  showWhoWeAre();
+}
+
+- (void) endPrefixMapping: (NSString *)_prefix
+{
+  showWhoWeAre();
+}
+
+- (NSString *) _valueForCSSIdentifier: (NSString *) primaryValue
+{
+  NSMutableString *value;
+  NSEnumerator *classes;
+  NSString *currentValue;
+
+  value = [NSMutableString new];
+  [value autorelease];
+
+  classes = [[primaryValue componentsSeparatedByString: @" "] objectEnumerator];
+  currentValue = [classes nextObject];
+  while (currentValue)
+    {
+      [value appendFormat: @"SOGoHTMLMail-%@ ", currentValue];
+      currentValue = [classes nextObject];
+    }
+
+  return value;
+}
+
+- (void) _appendStyle: (unichar *) _chars
+               length: (int) _len
+{
+  unsigned int count;
+  unichar *start, *currentChar;
+
+  start = _chars;
+  currentChar = start;
+  for (count = 0; count < _len; count++)
+    {
+      currentChar = _chars + count;
+      if (inCSSDeclaration)
+        {
+          if (*(char *) currentChar == '}')
+            inCSSDeclaration = NO;
+        }
+      else
+        {
+          if (*(char *) currentChar == '{')
+            inCSSDeclaration = YES;
+          else if (*(char *) currentChar == '.'
+                   || *(char *) currentChar == '#')
+            {
+              [css appendString: [NSString stringWithCharacters: start
+                                           length: (currentChar - start + 1)]];
+              [css appendString: @"SOGoHTMLMail-"];
+              start = currentChar + 1;
+            }
+        }
+    }
+  [css appendString: [NSString stringWithCharacters: start
+                               length: (currentChar - start + 1)]];
+}
+
+- (void) startElement: (NSString *) _localName
+            namespace: (NSString *) _ns
+              rawName: (NSString *) _rawName
+           attributes: (id <SaxAttributes>) _attributes
+{
+  unsigned int count, max;
+  NSString *name, *value;
+  NSMutableString *resultPart;
+  BOOL skipAttribute;
+
+  if (inStyle || inScript)
+    ;
+  else if ([_localName caseInsensitiveCompare: @"body"] == NSOrderedSame)
+    inBody = YES;
+  else if ([_localName caseInsensitiveCompare: @"script"] == NSOrderedSame)
+    inScript = YES;
+  else if ([_localName caseInsensitiveCompare: @"style"] == NSOrderedSame)
+    inStyle = YES;
+  else if (inBody)
+    {
+      resultPart = [NSMutableString new];
+      [resultPart appendFormat: @"<%@", _rawName];
+      
+      max = [_attributes count];
+      for (count = 0; count < max; count++)
+        {
+          skipAttribute = NO;
+          name = [_attributes nameAtIndex: count];
+          if ([name caseInsensitiveCompare: @"class"] == NSOrderedSame
+              || [name caseInsensitiveCompare: @"id"] == NSOrderedSame)
+            value = [self _valueForCSSIdentifier: [_attributes valueAtIndex: count]];
+          else if ([[name lowercaseString] hasPrefix: @"on"])
+            skipAttribute = YES;
+          else if ([name caseInsensitiveCompare: @"src"] == NSOrderedSame)
+            {
+              value = [_attributes valueAtIndex: count];
+              if ([value hasPrefix: @"cid:"])
+                {
+                  value = [attachmentIds
+                            objectForKey: [value substringFromIndex: 4]];
+                  skipAttribute = (value == nil);
+                }
+              else
+                skipAttribute = YES;
+            }
+          else
+            value = [_attributes valueAtIndex: count];
+          if (!skipAttribute)
+            [resultPart appendFormat: @" %@=\"%@\"",
+                        name, [value stringByReplacingString: @"\""
+                                     withString: @"\\\""]];
+        }
+
+      [resultPart appendString: @">"];
+      [result appendString: resultPart];
+    }
+}
+
+- (void) endElement: (NSString *) _localName
+          namespace: (NSString *) _ns
+            rawName: (NSString *) _rawName
+{
+  if (inStyle)
+    {
+     if ([_localName caseInsensitiveCompare: @"style"] == NSOrderedSame)
+       {
+         inStyle = NO;
+         inCSSDeclaration = NO;
+       }
+    }
+  else if (inScript)
+    inScript = ([_localName caseInsensitiveCompare: @"script"] != NSOrderedSame);
+  else if (inBody)
+    {
+      if ([_localName caseInsensitiveCompare: @"body"] == NSOrderedSame)
+        inBody = NO;
+      else
+        [result appendFormat: @"</%@>", _localName];
+    }
+}
+
+- (void) characters: (unichar *) _chars
+             length: (int) _len
+{
+  NSString *tmpString;
+
+  if (!inScript)
+    {
+      if (inStyle)
+        [self _appendStyle: _chars length: _len];
+      if (inBody)
+        {
+          tmpString = [NSString stringWithCharacters: _chars length: _len];
+          [result appendString: [tmpString stringByEscapingHTMLString]];
+        }
+    }
+}
+
+- (void) ignorableWhitespace: (unichar *) _chars
+                      length: (int) _len
+{
+  showWhoWeAre();
+}
+
+- (void) processingInstruction: (NSString *) _pi
+                          data: (NSString *) _data
+{
+  showWhoWeAre();
+}
+
+- (void) setDocumentLocator: (id <NSObject, SaxLocator>) _locator
+{
+  showWhoWeAre();
+}
+
+- (void) skippedEntity: (NSString *) _entityName
+{
+  showWhoWeAre();
+}
+
+/* SaxLexicalHandler */
+- (void) comment: (unichar *) _chars
+          length: (int) _len
+{
+  if (inStyle)
+    [self _appendStyle: _chars length: _len];
+}
+
+- (void) startDTD: (NSString *) _name
+         publicId: (NSString *) _pub
+         systemId: (NSString *) _sys
+{
+  showWhoWeAre();
+}
+
+- (void) endDTD
+{
+  showWhoWeAre();
+}
+
+- (void) startEntity: (NSString *) _name
+{
+  showWhoWeAre();
+}
+
+- (void) endEntity: (NSString *) _name
+{
+  showWhoWeAre();
+}
+
+- (void) startCDATA
+{
+  showWhoWeAre();
+}
+
+- (void) endCDATA
+{
+  showWhoWeAre();
+}
+
+@end
+
+@interface NSDictionary (SOGoDebug)
+
+- (void) dump;
+
+@end
+
+@implementation NSDictionary (SOGoDebug)
+
+- (void) dump
+{
+  NSEnumerator *keys;
+  NSString *key;
+  NSMutableString *dump;
+
+  dump = [NSMutableString new];
+  [dump appendFormat: @"\nNSDictionary dump (%@):\n", self];
+  keys = [[self allKeys] objectEnumerator];
+  key = [keys nextObject];
+  while (key)
+    {
+      [dump appendFormat: @"%@: %@\n", key, [self objectForKey: key]];
+      key = [keys nextObject];
+    }
+  [dump appendFormat: @"--- end ---\n"];
+
+  NSLog (dump);
+  [dump release];
+}
+
+@end
 
 @implementation UIxMailPartHTMLViewer
 
 @implementation UIxMailPartHTMLViewer
-@end /* UIxMailPartHTMLViewer */
+
+- (void) _convertReferencesForPart: (NSDictionary *) part
+                         withCount: (unsigned int) count
+                        andBaseURL: (NSString *) url
+                    intoDictionary: (NSMutableDictionary *) attachmentIds
+{
+  NSString *bodyId;
+
+  bodyId = [part objectForKey: @"bodyId"];
+  if ([bodyId length] > 0)
+    {
+      NSLog(@"%@", part);
+      if ([bodyId hasPrefix: @"<"])
+        bodyId = [bodyId substringFromIndex: 1];
+      if ([bodyId hasSuffix: @">"])
+        bodyId = [bodyId substringToIndex: [bodyId length] - 1];
+      [attachmentIds setObject: [url stringByAppendingFormat: @"/%d", count]
+                     forKey: bodyId];
+    }
+}
+
+- (NSDictionary *) _attachmentIds
+{
+  NSMutableDictionary *attachmentIds;
+  UIxMailPartViewer *parent;
+  unsigned int count, max;
+  NSString *baseURL;
+  NSArray *parts;
+
+  attachmentIds = [NSMutableDictionary new];
+  [attachmentIds autorelease];
+  
+  parent = [self parent];
+  if ([NSStringFromClass ([parent class])
+                         isEqualToString: @"UIxMailPartAlternativeViewer"])
+    {
+      baseURL = [[self clientObject] baseURLInContext: context];
+      parts = [[parent bodyInfo] objectForKey: @"parts"];
+      max = [parts count];
+      for (count = 0; count < max; count++)
+        [self _convertReferencesForPart: [parts objectAtIndex: count]
+              withCount: count + 1
+              andBaseURL: baseURL
+              intoDictionary: attachmentIds];
+    }
+
+  NSLog(@"attc: '%@'", attachmentIds);
+  return attachmentIds;
+}
+
+- (NSString *) flatContentAsString
+{
+  id <NSObject, SaxXMLReader> parser;
+  _UIxHTMLMailContentHandler *handler;
+  NSString *preparsedContent, *content, *css;
+
+  preparsedContent = [super flatContentAsString];
+  parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
+             createXMLReaderForMimeType: @"text/html"];
+
+  handler = [_UIxHTMLMailContentHandler new];
+  [handler setAttachmentIds: [self _attachmentIds]];
+  [parser setContentHandler: handler];
+  [parser setProperty: @"http://xml.org/sax/properties/lexical-handler"
+          to: handler];
+  [parser parseFromSource: preparsedContent];
+
+  css = [handler css];
+  if ([css length])
+    content
+      = [NSString stringWithFormat: @"<style type=\"text/css\">%@</style>%@",
+                  css, [handler result]];
+  else
+    content = [handler result];
+  [handler release];
+
+  return content;
+}
+
+@end
index 365d144e298f73701ff3e6bf43261bd78d466d76..7af72391c404cb078cc0f821b08f3ed0a47df0bc 100644 (file)
 }
 
 - (iCalEvent *)storedEvent {
 }
 
 - (iCalEvent *)storedEvent {
-  return [(SOGoAppointmentObject *)[self storedEventObject] event];
+  return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component];
 }
 
 /* organizer tracking */
 }
 
 /* organizer tracking */
index 72ca9452e7733660334185a4bd5dabfb6ac78f33..bb988c4031d34a3c36df4c774e3934e7eb0a05b6 100644 (file)
   }
   
   charset = [(NSDictionary *)
   }
   
   charset = [(NSDictionary *)
-             [(NSDictionary *)[self bodyInfo] objectForKey:@"parameterList"] 
-                                              objectForKey:@"charset"];
+             [(NSDictionary *)[self bodyInfo] objectForKey:@"parameterList"]
+              objectForKey:@"charset"];
   charset = [charset lowercaseString];
   charset = [charset lowercaseString];
-  
+
   // TODO: properly decode charset, might need to handle encoding?
   
   if ([charset length] > 0) {
   // TODO: properly decode charset, might need to handle encoding?
   
   if ([charset length] > 0) {
-    s = [NSString stringWithData:content usingEncodingNamed:charset];
+    s = [NSString stringWithData: content usingEncodingNamed: charset];
   }
   else {
   }
   else {
-    s = [[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding];
+    s = [[NSString alloc] initWithData: content encoding: NSUTF8StringEncoding];
     s = [s autorelease];
   }
   
     s = [s autorelease];
   }
   
index a743983fe3ed5f292f706fd573153966b43e55e3..e2a101ae07b96f8d90307ddf4bd0a4e3bdec7488 100644 (file)
@@ -178,9 +178,10 @@ static BOOL showNamedTextAttachmentsInline = NO;
   if ([mt isEqualToString:@"multipart"]) {
     if ([st isEqualToString:@"mixed"])
       return [self mixedViewer];
   if ([mt isEqualToString:@"multipart"]) {
     if ([st isEqualToString:@"mixed"])
       return [self mixedViewer];
-    if ([st isEqualToString:@"signed"])
+    else if ([st isEqualToString:@"signed"])
       return [self signedViewer];
       return [self signedViewer];
-    if ([st isEqualToString:@"alternative"])
+    else if ([st isEqualToString:@"alternative"]
+             || [st isEqualToString:@"related"])
       return [self alternativeViewer];
     
     if ([st isEqualToString:@"report"])
       return [self alternativeViewer];
     
     if ([st isEqualToString:@"report"])
index f8b1947392e72dbf896a6e279284531d0fa8c0f7..5c2d39c72de757a49824a40209b891d3aac3197e 100644 (file)
 {
   iCalCalendar *calendar;
   iCalEvent *appointment;
 {
   iCalCalendar *calendar;
   iCalEvent *appointment;
-  SOGoAppointmentObject *clientObject;
 
 
-  clientObject = [self clientObject];
   calendar = [iCalCalendar parseSingleFromSource: _iCalString];
   calendar = [iCalCalendar parseSingleFromSource: _iCalString];
-  appointment = [clientObject firstEventFromCalendar: calendar];
+  appointment = (iCalEvent *) [calendar firstChildWithTag: @"vevent"];
 
   return appointment;
 }
 
   return appointment;
 }
index cb4562abc09d27bee4896162ad8d2278f72883ca..14b3b6ea0216c2f36a1424d83cb75495bdc76328 100644 (file)
 
 - (iCalEvent *) appointment
 {
 
 - (iCalEvent *) appointment
 {
-  NSString *iCalString;
-  iCalCalendar *calendar;
   SOGoAppointmentObject *clientObject;
   SOGoAppointmentObject *clientObject;
-    
-  if (appointment != nil)
-    return appointment;
-
-  clientObject = [self clientObject];
-
-  iCalString = [[self clientObject] valueForKey:@"iCalString"];
-  if (![iCalString isNotNull] || [iCalString length] == 0) {
-    [self errorWithFormat:@"(%s): missing iCal string!", 
-            __PRETTY_FUNCTION__];
-    return nil;
-  }
 
 
-  calendar = [iCalCalendar parseSingleFromSource: iCalString];
-  appointment = [clientObject firstEventFromCalendar: calendar];
-  [appointment retain];
+  if (!appointment)
+    {
+      clientObject = [self clientObject];
+      appointment = (iCalEvent *) [clientObject component];
+      [appointment retain];
+    }
 
   return appointment;
 }
 
   return appointment;
 }
index 2b958f1aa428e68ee93faf1237ea157077ea19c7..e23e664a819b78383ae0a8aa5ee4c49e22f7e234 100644 (file)
 {
   NSString *filename;
   iCalEntityObject *calObject;
 {
   NSString *filename;
   iCalEntityObject *calObject;
-  id co;
+  SOGoCalendarComponent *co;
 
   if (componentLoaded)
     {
       co = [self clientObject];
 
   if (componentLoaded)
     {
       co = [self clientObject];
-      if ([co isKindOfClass: [SOGoAppointmentObject class]])
-        {
-          calObject = (iCalEntityObject *) [co event];
-          filename = [self _toolbarForCalObject: calObject];
-        }
-      else if ([co isKindOfClass: [SOGoTaskObject class]])
-        {
-          calObject = (iCalEntityObject *) [co task];
-          filename = [self _toolbarForCalObject: calObject];
-        }
-      else
-        filename = @"";
+      calObject = [co component];
+      filename = [self _toolbarForCalObject: calObject];
     }
   else
     filename = @"";
     }
   else
     filename = @"";
index 9335c23a105340456717a5ac26326755be2de4a5..8ff0ff6e14c946f7188628c3907f85397b5b367c 100644 (file)
 {
   iCalCalendar *calendar;
   iCalToDo *task;
 {
   iCalCalendar *calendar;
   iCalToDo *task;
-  SOGoTaskObject *clientObject;
 
 
-  clientObject = [self clientObject];
   calendar = [iCalCalendar parseSingleFromSource: _iCalString];
   calendar = [iCalCalendar parseSingleFromSource: _iCalString];
-  task = [clientObject firstTaskFromCalendar: calendar];
+  task = (iCalToDo *) [calendar firstChildWithTag: @"vtodo"];
 
   return task;
 }
 
   return task;
 }
   newStatus = [[self queryParameterForKey: @"status"] intValue];
 
   taskObject = [self clientObject];
   newStatus = [[self queryParameterForKey: @"status"] intValue];
 
   taskObject = [self clientObject];
-  task = [taskObject task];
+  task = (iCalToDo *) [taskObject component];
   switch (newStatus)
     {
     case 1:
   switch (newStatus)
     {
     case 1:
index 71bf79c8224d1072b5d74fb56b76e9515c1c67e1..0f31e9241874ac7bea1ecdeb1b0313ee0e187117 100644 (file)
 
 - (iCalToDo *) task
 {
 
 - (iCalToDo *) task
 {
-  NSString *iCalString;
-  iCalCalendar *calendar;
   SOGoTaskObject *clientObject;
   SOGoTaskObject *clientObject;
-    
-  if (task != nil)
-    return task;
-
-  clientObject = [self clientObject];
-
-  iCalString = [[self clientObject] valueForKey:@"iCalString"];
-  if (![iCalString isNotNull] || [iCalString length] == 0) {
-    [self errorWithFormat:@"(%s): missing iCal string!", 
-            __PRETTY_FUNCTION__];
-    return nil;
-  }
 
 
-  calendar = [iCalCalendar parseSingleFromSource: iCalString];
-  task = [clientObject firstTaskFromCalendar: calendar];
-  [task retain];
+  if (!task)
+    {
+      clientObject = [self clientObject];
+      task = (iCalToDo *) [clientObject component];
+      [task retain];
+    }
 
   return task;
 }
 
   return task;
 }
index e9f0cf4c0185b61cb0b2c304e54550157be59fa5..f08d54d54e3c8c381f3057ec58e1bf6e3c7aaebf 100644 (file)
           actionName  = "delete";
         };
         edit = { 
           actionName  = "delete";
         };
         edit = { 
-          protectedBy = "Change Images and Files";
+          protectedBy = "View";
           pageName    = "UIxTaskEditor"; 
         };
         editAsTask = { 
           pageName    = "UIxTaskEditor"; 
         };
         editAsTask = { 
-          protectedBy = "Change Images and Files";
+          protectedBy = "View";
           pageName    = "UIxTaskEditor"; 
         };
         save = { 
           pageName    = "UIxTaskEditor"; 
         };
         save = { 
index 8ca1d5f73d606be7cd42473252afccba60228665..bafb0547038625b140fd6a937caf541e0ea6ffd5 100644 (file)
@@ -1,23 +1,9 @@
 <?xml version="1.0" standalone="yes"?>
 <?xml version="1.0" standalone="yes"?>
-<div xmlns="http://www.w3.org/1999/xhtml"
-     xmlns:var="http://www.skyrix.com/od/binding"
-     xmlns:label="OGo:label"
-     class="linked_attachment_frame"
->
-  <!-- TODO: make an optional iframe -->
-  <!-- TODO: add a server side 'safe' renderer -->
-  
-  <div class="linked_attachment_body">
-    <a var:href="pathToAttachment"
-       var:title="filenameForDisplay"
-       ><var:string value="filenameForDisplay" /></a>
-    <div class="linked_attachment_meta">
-      <var:string label:value="Type" />:
-      <var:string value="bodyInfo.type" /> / 
-      <var:string value="bodyInfo.subtype" />,
-
-      <var:string label:value="Size" />:
-      <var:string value="bodyInfo.size" formatter="sizeFormatter" />
-    </div>
-  </div>
-</div>
+<div
+  xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:var="http://www.skyrix.com/od/binding"
+  xmlns:const="http://www.skyrix.com/od/constant"
+  xmlns:rsrc="OGo:url"
+  xmlns:label="OGo:label"
+  class="mailer_htmlcontent"
+><var:string value="flatContentAsString" const:escapeHTML="NO" /></div>
index 1997ee89df67caa6571d696c9feb753d697be534..f10b370af39fb0871aad5e3460840b698afc3175 100644 (file)
@@ -72,6 +72,13 @@ DIV#messageContent
   background: #fff;
 }
 
   background: #fff;
 }
 
+DIV#messageContent P IMG
+{
+  border: 0px;
+  vertical-align: middle;
+  margin-right: 1em;
+}
+
 DIV#folderTreeContent
 {
   position: absolute;
 DIV#folderTreeContent
 {
   position: absolute;
@@ -84,18 +91,6 @@ DIV#folderTreeContent
   border: 1px solid #fff;
 }
 
   border: 1px solid #fff;
 }
 
-DIV#messageContent P
-{
-  line-height: 3em;
-}
-
-DIV#messageContent P IMG
-{
-  border: 0px;
-  vertical-align: middle;
-  margin-right: 1em;
-}
-
 .aptview_title
 {
   color: #000000;
 .aptview_title
 {
   color: #000000;
@@ -378,6 +373,23 @@ DIV.mailer_plaincontent
   padding: 0px;
 }
 
   padding: 0px;
 }
 
+DIV.mailer_plaincontent P
+{
+  line-height: 3em;
+  height: auto;
+  margin: 0px;
+  padding: 0px;
+}
+
+DIV.mailer_htmlcontent P
+{ 
+  white-space: normal;
+  font-family: serif;
+  font-size: inherit;
+  margin: 0px;
+  padding: 0px;
+}
+
 /* attachment editor */
 
 form#attachment_form
 /* attachment editor */
 
 form#attachment_form