See ChangeLog

Monotone-Parent: 728de9d1f91919c2ef87a31aa2d11b9b1a3a9835
Monotone-Revision: e5e46473685093f9076981f90edbe581992247e7

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2012-08-27T20:35:10
maint-2.0.2
Francis Lachapelle 2012-08-27 20:35:10 +00:00
parent 4d71ec17f6
commit da6b5696a0
15 changed files with 368 additions and 133 deletions

View File

@ -1,11 +1,19 @@
2012-08-27 Francis Lachapelle <flachapelle@inverse.ca> 2012-08-27 Francis Lachapelle <flachapelle@inverse.ca>
* SoObjects/Appointments/SOGoAptMailInvitation.m,
SoObjects/Appointments/SOGoAptMailNotification.m,
SoObjects/Appointments/SOGoAptMailDeletion.m,
SoObjects/Appointments/SOGoAptMailUpdate.m,
SoObjects/Appointments/SOGoAptMailICalReply.m,
SoObjects/Appointments/SOGoCalendarComponent.m: send HTML messages
instead of text/plain.
* UI/WebServerResources/generic.js (openMailTo): mail addresses * UI/WebServerResources/generic.js (openMailTo): mail addresses
must now be separated by semi-colons and not commas. This allow must now be separated by semi-colons and not commas. This allow
display names to contain commas. display names to contain commas.
* UI/WebServerResources/SchedulerUI.js (tasksListCallback): prefix * UI/WebServerResources/SchedulerUI.js (tasksListCallback): prefix
tasks with a color box insted of changing the task's background color. tasks with a color box instead of changing the task's background color.
* UI/Scheduler/UIxCalListingActions.m * UI/Scheduler/UIxCalListingActions.m
(-_getStatusClassForStatusCode:andEndDateStamp::): set the (-_getStatusClassForStatusCode:andEndDateStamp::): set the

1
NEWS
View File

@ -5,6 +5,7 @@ Enhancements
executed, no matter if a previous condition matches) executed, no matter if a previous condition matches)
- improved tasks list display - improved tasks list display
- RPM packages now treat logrotate file as a config file - RPM packages now treat logrotate file as a config file
- completed the transition from text/plain message templates to HTML
Bug Fixes Bug Fixes
- fixed passwords that would be prefixed with '{none}' when not using a - fixed passwords that would be prefixed with '{none}' when not using a

View File

@ -11,9 +11,9 @@ vtodo_class2 = "(Confidential task)";
"The event \"%{Summary}\" was created" = "The event \"%{Summary}\" was created"; "The event \"%{Summary}\" was created" = "The event \"%{Summary}\" was created";
"The event \"%{Summary}\" was deleted" = "The event \"%{Summary}\" was deleted"; "The event \"%{Summary}\" was deleted" = "The event \"%{Summary}\" was deleted";
"The event \"%{Summary}\" was updated" = "The event \"%{Summary}\" was updated"; "The event \"%{Summary}\" was updated" = "The event \"%{Summary}\" was updated";
"The following attendees(s) were notified:" = "The following attendees(s) were notified:"; "The following attendees(s) were notified:" = "The following attendee(s) were notified:";
"The following attendees(s) were added:" = "The following attendees(s) were added:"; "The following attendees(s) were added:" = "The following attendee(s) were added:";
"The following attendees(s) were removed:" = "The following attendees(s) were removed:"; "The following attendees(s) were removed:" = "The following attendee(s) were removed:";
/* IMIP messages */ /* IMIP messages */
"startDate_label" = "Start:"; "startDate_label" = "Start:";

View File

@ -44,27 +44,14 @@
- (NSString *) getBody - (NSString *) getBody
{ {
NSString *bodyFormat; NSString *body;
if (!values) if (!values)
[self setupValues]; [self setupValues];
if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) body = [[self generateResponse] contentAsString];
bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled"
@" this event: %{Summary}.\n\n"
@"Start: %{StartDate} at %{StartTime}\n"
@"End: %{EndDate} at %{EndTime}\n"
@"Description: %{Description}")
inContext: context];
else
bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled"
@" this event: %{Summary}.\n\n"
@"Start: %{StartDate}\n"
@"End: %{EndDate}\n"
@"Description: %{Description}")
inContext: context];
return [values keysWithFormat: bodyFormat]; return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
} }
@end @end

View File

@ -1,6 +1,6 @@
/* SOGoAptMailICalReply - this file is part of SOGo /* SOGoAptMailICalReply - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc. * Copyright (C) 2010-2012 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -19,6 +19,7 @@
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#import <Foundation/NSCharacterSet.h>
#import <SOGo/NSDictionary+Utilities.h> #import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSObject+Utilities.h> #import <SOGo/NSObject+Utilities.h>
@ -105,14 +106,11 @@
return [values keysWithFormat: subjectFormat]; return [values keysWithFormat: subjectFormat];
} }
- (NSString *) getBody - (NSString *) bodyStartText
{ {
NSString *bodyFormat; NSString *bodyFormat;
NSString *partStat, *delegate; NSString *partStat, *delegate;
if (!values)
[self setupValues];
partStat = [[attendee partStat] lowercaseString]; partStat = [[attendee partStat] lowercaseString];
if ([partStat isEqualToString: @"accepted"]) if ([partStat isEqualToString: @"accepted"])
bodyFormat = @"%{Attendee} %{SentByText}has accepted your event invitation."; bodyFormat = @"%{Attendee} %{SentByText}has accepted your event invitation.";
@ -135,7 +133,19 @@
else else
bodyFormat = @"%{Attendee} %{SentByText}has not yet decided upon your event invitation."; bodyFormat = @"%{Attendee} %{SentByText}has not yet decided upon your event invitation.";
return [values keysWithFormat: [self labelForKey: bodyFormat inContext: context]]; return [values keysWithFormat: bodyFormat];
}
- (NSString *) getBody
{
NSString *body;
if (!values)
[self setupValues];
body = [[self generateResponse] contentAsString];
return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
} }
@end @end

View File

@ -49,27 +49,14 @@
- (NSString *) getBody - (NSString *) getBody
{ {
NSString *bodyFormat; NSString *body;
if (!values) if (!values)
[self setupValues]; [self setupValues];
if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) body = [[self generateResponse] contentAsString];
bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you"
@" to %{Summary}.\n\n"
@"Start: %{StartDate} at %{StartTime}\n"
@"End: %{EndDate} at %{EndTime}\n"
@"Description: %{Description}")
inContext: context];
else
bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you"
@" to %{Summary}.\n\n"
@"Start: %{StartDate}\n"
@"End: %{EndDate}\n"
@"Description: %{Description}")
inContext: context];
return [values keysWithFormat: bodyFormat]; return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
} }
@end @end

View File

@ -1,15 +1,15 @@
/* /*
Copyright (C) 2006-2010 Inverse inc. Copyright (C) 2006-2012 Inverse inc.
Copyright (C) 2000-2005 SKYRIX Software AG Copyright (C) 2000-2005 SKYRIX Software AG
This file is part of OpenGroupware.org. This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under SOGo 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 the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details. License for more details.
@ -30,6 +30,7 @@
@class NSString; @class NSString;
@class NSTimeZone; @class NSTimeZone;
@class iCalEvent; @class iCalEvent;
@class SOGoDateFormatter;
/* /*
* NOTE: We inherit from SoComponent in order to get the correct * NOTE: We inherit from SoComponent in order to get the correct
@ -47,6 +48,7 @@
NSCalendarDate *newEndDate; NSCalendarDate *newEndDate;
NSString *organizerName; NSString *organizerName;
NSMutableDictionary *values; NSMutableDictionary *values;
SOGoDateFormatter *dateFormatter;
} }
- (void) setupValues; - (void) setupValues;
@ -66,6 +68,12 @@
- (NSCalendarDate *) oldEndDate; - (NSCalendarDate *) oldEndDate;
- (NSCalendarDate *) newEndDate; - (NSCalendarDate *) newEndDate;
- (NSString *) sentByText;
- (NSString *) formattedAptStartDate;
- (NSString *) formattedAptStartTime;
- (NSString *) formattedAptEndDate;
- (NSString *) formattedAptEndTime;
- (NSString *) getSubject; - (NSString *) getSubject;
- (NSString *) getBody; - (NSString *) getBody;

View File

@ -49,6 +49,7 @@
{ {
apt = nil; apt = nil;
values = nil; values = nil;
dateFormatter = RETAIN([[context activeUser] dateFormatterInContext: context]);
} }
return self; return self;
@ -65,6 +66,7 @@
[newStartDate release]; [newStartDate release];
[oldEndDate release]; [oldEndDate release];
[newEndDate release]; [newEndDate release];
[dateFormatter release];
[super dealloc]; [super dealloc];
} }
@ -153,7 +155,105 @@
return organizerName; return organizerName;
} }
/* Helpers */ - (NSString *) sentByText
{
NSDictionary *sentByValues;
NSString *sentByText;
id value;
sentByText = @"";
if (organizerName)
{
value = [[apt organizer] sentBy];
if (value && [value length])
{
sentByValues = [NSDictionary dictionaryWithObject: value
forKey: @"SentBy"];
sentByText
= [sentByValues keysWithFormat: [self
labelForKey: @"(sent by %{SentBy}) "
inContext: context]];
}
}
return sentByText;
}
- (NSString *) formattedAptStartDate
{
NSString *s;
id value;
value = [self newStartDate];
s = @"";
if (value)
s = [dateFormatter formattedDate: value];
return s;
}
- (NSString *) formattedAptStartTime
{
NSString *s;
id value;
value = [self newStartDate];
s = @"";
if (value && ![apt isAllDay])
s = [dateFormatter formattedTime: value];
return s;
}
- (NSString *) formattedAptEndDate
{
NSString *s;
id value;
value = [self newEndDate];
s = @"";
if (value)
s = [dateFormatter formattedDate: value];
return s;
}
- (NSString *) formattedAptEndTime
{
NSString *s;
id value;
value = [self newEndDate];
s = @"";
if (value && ![apt isAllDay])
s = [dateFormatter formattedTime: value];
return s;
}
- (void) setupValues
{
SOGoUser *user;
id value;
user = [context activeUser];
viewTZ = [[user userDefaults] timeZone];
[viewTZ retain];
values = [NSMutableDictionary new];
value = [self summary];
if (!value)
value = @"";
[values setObject: value forKey: @"Summary"];
}
/* Generate Response */ /* Generate Response */
@ -171,59 +271,4 @@
return nil; return nil;
} }
- (void) setupValues
{
NSString *sentBy, *sentByText, *description;
NSCalendarDate *date;
NSDictionary *sentByValues;
SOGoUser *user;
SOGoDateFormatter *dateFormatter;
user = [context activeUser];
viewTZ = [[user userDefaults] timeZone];
[viewTZ retain];
values = [NSMutableDictionary new];
[values setObject: [self summary] forKey: @"Summary"];
if (organizerName)
{
[values setObject: organizerName forKey: @"Organizer"];
sentBy = [[apt organizer] sentBy];
if ([sentBy length])
{
sentByValues = [NSDictionary dictionaryWithObject: sentBy
forKey: @"SentBy"];
sentByText
= [sentByValues keysWithFormat: [self
labelForKey: @"(sent by %{SentBy}) "
inContext: context]];
}
else
sentByText = @"";
[values setObject: sentByText forKey: @"SentByText"];
}
dateFormatter = [[context activeUser] dateFormatterInContext: context];
date = [self newStartDate];
[values setObject: [dateFormatter shortFormattedDate: date]
forKey: @"StartDate"];
if (![apt isAllDay])
[values setObject: [dateFormatter formattedTime: date]
forKey: @"StartTime"];
date = [self newEndDate];
[values setObject: [dateFormatter shortFormattedDate: date]
forKey: @"EndDate"];
if (![apt isAllDay])
[values setObject: [dateFormatter formattedTime: date]
forKey: @"EndTime"];
description = [[self apt] comment];
[values setObject: (description ? description : @"")
forKey: @"Description"];
}
@end @end

View File

@ -33,10 +33,31 @@
#import "SOGoAptMailNotification.h" #import "SOGoAptMailNotification.h"
@interface SOGoAptMailUpdate : SOGoAptMailNotification @interface SOGoAptMailUpdate : SOGoAptMailNotification
{
NSMutableDictionary *changes;
NSString *currentItem;
}
@end @end
@implementation SOGoAptMailUpdate @implementation SOGoAptMailUpdate
- (id) init
{
self = [super init];
changes = [[NSMutableDictionary alloc] init];
return self;
}
- (void) dealloc
{
RELEASE(currentItem);
RELEASE(changes);
[super dealloc];
}
- (NSString *) valueForProperty: (NSString *) property - (NSString *) valueForProperty: (NSString *) property
withDateFormatter: (SOGoDateFormatter *) dateFormatter withDateFormatter: (SOGoDateFormatter *) dateFormatter
{ {
@ -64,7 +85,10 @@
if ([valueType isEqualToString: @"date"]) if ([valueType isEqualToString: @"date"])
{ {
[value setTimeZone: viewTZ]; [value setTimeZone: viewTZ];
value = [dateFormatter formattedDateAndTime: value]; if ([apt isAllDay])
value = [dateFormatter formattedDate: value];
else
value = [dateFormatter formattedDateAndTime: value];
} }
} }
else else
@ -75,15 +99,13 @@
- (void) _setupBodyContentWithFormatter: (SOGoDateFormatter *) dateFormatter - (void) _setupBodyContentWithFormatter: (SOGoDateFormatter *) dateFormatter
{ {
NSArray *updatedProperties;
NSMutableString *bodyContent;
NSString *property, *label, *value; NSString *property, *label, *value;
NSArray *updatedProperties;
int count, max; int count, max;
updatedProperties = [[iCalEventChanges changesFromEvent: previousApt updatedProperties = [[iCalEventChanges changesFromEvent: previousApt
toEvent: apt] toEvent: apt]
updatedProperties]; updatedProperties];
bodyContent = [NSMutableString new];
max = [updatedProperties count]; max = [updatedProperties count];
for (count = 0; count < max; count++) for (count = 0; count < max; count++)
{ {
@ -96,27 +118,40 @@
label = [self labelForKey: [NSString stringWithFormat: @"%@_label", label = [self labelForKey: [NSString stringWithFormat: @"%@_label",
property] property]
inContext: context]; inContext: context];
[bodyContent appendFormat: @" %@ %@\n", label, value]; [changes setObject: value forKey: label];
} }
} }
[values setObject: bodyContent forKey: @"_bodyContent"];
[bodyContent release];
} }
- (void) _setupBodyValuesWithFormatter: (SOGoDateFormatter *) dateFormatter - (NSArray *) allChangesList
{
return [changes allKeys];
}
- (void) setCurrentItem: (NSString *) theItem
{
ASSIGN(currentItem, theItem);
}
- (NSString *) currentItem
{
return currentItem;
}
- (NSString *) valueForCurrentItem
{
return [changes objectForKey: currentItem];
}
- (NSString *) bodyStartText
{ {
NSString *bodyText; NSString *bodyText;
bodyText = [self labelForKey: @"The following parameters have changed" bodyText = [self labelForKey: @"The following parameters have changed"
@" in the \"%{Summary}\" meeting:" @" in the \"%{Summary}\" meeting:"
inContext: context]; inContext: context];
[values setObject: [values keysWithFormat: bodyText]
forKey: @"_bodyStart"]; return [values keysWithFormat: bodyText];
[self _setupBodyContentWithFormatter: dateFormatter];
[values setObject: [self labelForKey: @"Please accept"
@" or decline those changes."
inContext: context]
forKey: @"_bodyEnd"];
} }
- (void) setupValues - (void) setupValues
@ -136,7 +171,7 @@
[values setObject: [dateFormatter formattedTime: date] [values setObject: [dateFormatter formattedTime: date]
forKey: @"OldStartTime"]; forKey: @"OldStartTime"];
[self _setupBodyValuesWithFormatter: dateFormatter]; [self _setupBodyContentWithFormatter: dateFormatter];
} }
- (NSString *) getSubject - (NSString *) getSubject
@ -162,11 +197,14 @@
- (NSString *) getBody - (NSString *) getBody
{ {
NSString *body;
if (!values) if (!values)
[self setupValues]; [self setupValues];
return [values keysWithFormat: body = [[self generateResponse] contentAsString];
@"%{_bodyStart}\n%{_bodyContent}\n%{_bodyEnd}\n"];
return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
} }
@end @end

View File

@ -845,8 +845,8 @@
/* text part */ /* text part */
headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
[headerMap setObject: @"text/plain; charset=\"UTF-8\"" [headerMap setObject: @"text/html; charset=utf-8"
forKey: @"content-type"]; forKey: @"content-type"];
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap]; bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
[bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]]; [bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]];
@ -927,8 +927,8 @@
/* text part */ /* text part */
headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
[headerMap setObject: @"text/plain; charset=utf-8" [headerMap setObject: @"text/html; charset=utf-8"
forKey: @"content-type"]; forKey: @"content-type"];
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap]; bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
bodyData = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding]; bodyData = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding];
[bodyPart setBody: bodyData]; [bodyPart setBody: bodyData];

View File

@ -1,3 +1,44 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container> <!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container> <html
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">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
h1 small { font-size: 12px; color: #999; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; color: #999; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<var:if condition="apt.location.length"
><dt><var:string label:value="location_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.location" const:escapeHTML="NO"/></dd></var:if>
<dt><var:string label:value="startDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptStartDate" const:escapeHTML="NO"
/><var:if condition="formattedAptStartTime.length"> - <var:string value="formattedAptStartTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<dt><var:string label:value="endDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptEndDate" const:escapeHTML="NO"
/><var:if condition="formattedAptEndTime.length"> - <var:string value="formattedAptEndTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<var:if condition="apt.comment.length"
><dt><var:string label:value="comment_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.comment" const:escapeHTML="NO"/></dd></var:if>
</dl>
</div>
</body>
</html>

View File

@ -1,3 +1,30 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container> <!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container> <html
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">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/></h1>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string value="bodyStartText" const:escapeHTML="NO"/></dd>
</dl>
</div>
</body>
</html>

View File

@ -1,3 +1,44 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container> <!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container> <html
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">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
h1 small { font-size: 12px; color: #999; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<var:if condition="apt.location.length"
><dt><var:string label:value="location_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.location" const:escapeHTML="NO"/></dd></var:if>
<dt><var:string label:value="startDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptStartDate" const:escapeHTML="NO"
/><var:if condition="formattedAptStartTime.length"> - <var:string value="formattedAptStartTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<dt><var:string label:value="endDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptEndDate" const:escapeHTML="NO"
/><var:if condition="formattedAptEndTime.length"> - <var:string value="formattedAptEndTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<var:if condition="apt.comment.length"
><dt><var:string label:value="comment_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.comment" const:escapeHTML="NO"/></dd></var:if>
</dl>
</div>
</body>
</html>

View File

@ -9,7 +9,7 @@
<head> <head>
<style type="text/css"> <style type="text/css">
.container { width: 600px; } .container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; } h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; } dt { font-weight: bold; line-height: 17px; }

View File

@ -1,3 +1,45 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container> <!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container> <html
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">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
h1 small { font-size: 12px; color: #999; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string value="bodyStartText" const:escapeHTML="NO"/></dd>
</dl>
<dl class="dl-horizontal">
<var:foreach list="allChangesList" item="currentItem"
><dt><var:string var:value="currentItem"/></dt>
<dd><var:string var:value="valueForCurrentItem"/></dd>
</var:foreach>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string label:value="Please accept or decline those changes." const:escapeHTML="NO"/></dd>
</dl>
</div>
</body>
</html>