Merge to 2.2.9
@@ -14,3 +14,5 @@ SoObjects/SOGo/derived_src/
|
||||
Tests/*/config.py
|
||||
*.pyc
|
||||
._*
|
||||
Documentation/*.docbook
|
||||
Documentation/*.pdf
|
||||
|
||||
@@ -33,14 +33,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGMail/NGMailAddress.h>
|
||||
#import <NGMail/NGMailAddressParser.h>
|
||||
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
@implementation NGMimeMessage (ActiveSync)
|
||||
|
||||
- (NSArray *) allRecipients
|
||||
{
|
||||
NSEnumerator *enumerator, *addressList;
|
||||
NSMutableArray *recipients;
|
||||
NSEnumerator *enumerator;
|
||||
NGMailAddressParser *parser;
|
||||
NGMailAddress *address;
|
||||
NSString *s;
|
||||
|
||||
recipients = [NSMutableArray array];
|
||||
@@ -48,13 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
enumerator = [[self headersForKey: @"to"] objectEnumerator];
|
||||
while ((s = [enumerator nextObject]))
|
||||
{
|
||||
[recipients addObject: [s pureEMailAddress]];
|
||||
parser = [NGMailAddressParser mailAddressParserWithString: s];
|
||||
addressList = [[parser parseAddressList] objectEnumerator];
|
||||
|
||||
while ((address = [addressList nextObject]))
|
||||
[recipients addObject: [address address]];
|
||||
}
|
||||
|
||||
enumerator = [[self headersForKey: @"cc"] objectEnumerator];
|
||||
while ((s = [enumerator nextObject]))
|
||||
{
|
||||
[recipients addObject: [s pureEMailAddress]];
|
||||
parser = [NGMailAddressParser mailAddressParserWithString: s];
|
||||
addressList = [[parser parseAddressList] objectEnumerator];
|
||||
|
||||
while ((address = [addressList nextObject]))
|
||||
[recipients addObject: [address address]];
|
||||
}
|
||||
|
||||
return recipients;
|
||||
|
||||
@@ -63,8 +63,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
s = [self stringByEscapingHTMLString];
|
||||
|
||||
return [[s componentsSeparatedByCharactersInSet: [self safeCharacterSet]]
|
||||
componentsJoinedByString: @""];
|
||||
return [s safeString];
|
||||
}
|
||||
|
||||
- (int) activeSyncFolderType
|
||||
|
||||
@@ -236,7 +236,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
iCalAlarm *alarm;
|
||||
|
||||
alarm = [[self alarms] objectAtIndex: 0];
|
||||
alarm = [self firstDisplayOrAudioAlarm];
|
||||
[s appendString: [alarm activeSyncRepresentationInContext: context]];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,507 @@
|
||||
commit c0e8eb6ce3b2501a0439a95d6d4bfcb9b6c17cf0
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 26 14:29:20 2014 -0400
|
||||
|
||||
Adjusted the doc for TB31
|
||||
|
||||
M Documentation/SOGoMozillaThunderbirdConfigurationGuide.asciidoc
|
||||
|
||||
commit 4be2ddb79339eb16d40404fb71b999c543ea395f
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Sep 26 14:23:39 2014 -0400
|
||||
|
||||
Update translations
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
|
||||
M SoObjects/Appointments/Russian.lproj/Localizable.strings
|
||||
M UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/Common/Czech.lproj/Localizable.strings
|
||||
M UI/Common/Dutch.lproj/Localizable.strings
|
||||
M UI/Common/Finnish.lproj/Localizable.strings
|
||||
M UI/Common/French.lproj/Localizable.strings
|
||||
M UI/Common/German.lproj/Localizable.strings
|
||||
M UI/Common/Hungarian.lproj/Localizable.strings
|
||||
M UI/Common/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/Common/Polish.lproj/Localizable.strings
|
||||
M UI/Common/Russian.lproj/Localizable.strings
|
||||
M UI/Common/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/MailerUI/Czech.lproj/Localizable.strings
|
||||
M UI/MailerUI/Dutch.lproj/Localizable.strings
|
||||
M UI/MailerUI/Finnish.lproj/Localizable.strings
|
||||
M UI/MailerUI/German.lproj/Localizable.strings
|
||||
M UI/MailerUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/MailerUI/Polish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Russian.lproj/Localizable.strings
|
||||
M UI/MailerUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Czech.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Dutch.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Finnish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/German.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Polish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Russian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/Scheduler/Czech.lproj/Localizable.strings
|
||||
M UI/Scheduler/Dutch.lproj/Localizable.strings
|
||||
M UI/Scheduler/Finnish.lproj/Localizable.strings
|
||||
M UI/Scheduler/German.lproj/Localizable.strings
|
||||
M UI/Scheduler/Hungarian.lproj/Localizable.strings
|
||||
M UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/Scheduler/Polish.lproj/Localizable.strings
|
||||
M UI/Scheduler/Russian.lproj/Localizable.strings
|
||||
M UI/Scheduler/SpanishSpain.lproj/Localizable.strings
|
||||
|
||||
commit 5744d1847447317caec390b61db4252ab245d71c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 26 14:15:32 2014 -0400
|
||||
|
||||
Updated scripts for TB31
|
||||
|
||||
M Scripts/updates.php
|
||||
|
||||
commit 9e1423cd4a7d0df284645449b1c37c2b8cec32dd
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Sep 26 13:58:28 2014 -0400
|
||||
|
||||
New font for asciidoc documentation
|
||||
|
||||
We now use Lato.
|
||||
|
||||
M Documentation/SOGoInstallationGuide.asciidoc
|
||||
M Documentation/docbook/xsl/sogo-fo-article.xsl
|
||||
M Documentation/docbook/xsl/sogo-fo.xsl
|
||||
M Documentation/docinfo.xml
|
||||
D Documentation/fonts/PALATINO.TTF
|
||||
D Documentation/fonts/deliciousitalic.ttf
|
||||
D Documentation/fonts/deliciousitalic.xml
|
||||
D Documentation/fonts/deliciousroman.ttf
|
||||
D Documentation/fonts/deliciousroman.xml
|
||||
M Documentation/fonts/fop-config.xml
|
||||
A Documentation/fonts/lato/Lato-Black.ttf
|
||||
A Documentation/fonts/lato/Lato-Black.xml
|
||||
A Documentation/fonts/lato/Lato-BlackItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-BlackItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Bold.ttf
|
||||
A Documentation/fonts/lato/Lato-Bold.xml
|
||||
A Documentation/fonts/lato/Lato-BoldItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-BoldItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Hairline.ttf
|
||||
A Documentation/fonts/lato/Lato-Hairline.xml
|
||||
A Documentation/fonts/lato/Lato-HairlineItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-HairlineItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Heavy.ttf
|
||||
A Documentation/fonts/lato/Lato-Heavy.xml
|
||||
A Documentation/fonts/lato/Lato-HeavyItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-HeavyItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Italic.ttf
|
||||
A Documentation/fonts/lato/Lato-Italic.xml
|
||||
A Documentation/fonts/lato/Lato-Light.ttf
|
||||
A Documentation/fonts/lato/Lato-Light.xml
|
||||
A Documentation/fonts/lato/Lato-LightItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-LightItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Medium.ttf
|
||||
A Documentation/fonts/lato/Lato-Medium.xml
|
||||
A Documentation/fonts/lato/Lato-MediumItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-MediumItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Regular.ttf
|
||||
A Documentation/fonts/lato/Lato-Regular.xml
|
||||
A Documentation/fonts/lato/Lato-Semibold.ttf
|
||||
A Documentation/fonts/lato/Lato-Semibold.xml
|
||||
A Documentation/fonts/lato/Lato-SemiboldItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-SemiboldItalic.xml
|
||||
A Documentation/fonts/lato/Lato-Thin.ttf
|
||||
A Documentation/fonts/lato/Lato-Thin.xml
|
||||
A Documentation/fonts/lato/Lato-ThinItalic.ttf
|
||||
A Documentation/fonts/lato/Lato-ThinItalic.xml
|
||||
A Documentation/fonts/lato/SIL Open Font License.txt
|
||||
D Documentation/fonts/oflgoudystm.ttf
|
||||
D Documentation/fonts/oflgoudystm.xml
|
||||
D Documentation/fonts/oflgoudystmitalic.ttf
|
||||
D Documentation/fonts/oflgoudystmitalic.xml
|
||||
D Documentation/fonts/palatino.xml
|
||||
M Documentation/images/architecture.png
|
||||
M Documentation/images/openchange.png
|
||||
M Documentation/includes/commercial-support.asciidoc
|
||||
M Documentation/includes/global-attributes.asciidoc
|
||||
M NEWS
|
||||
|
||||
commit 275eebde0fb77535a0d2d420e20f8431a8d65384
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 26 10:53:01 2014 -0400
|
||||
|
||||
Updated NEWS file for the release
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 0b6e3dc22d9a4f990ea981c4161846c6f889fa02
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Sep 25 09:25:13 2014 -0400
|
||||
|
||||
Fix for bug #589
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/iCalToDo+SOGo.m
|
||||
M UI/Scheduler/UIxTaskEditor.m
|
||||
|
||||
commit 3675220756f1bedc3828e892235a9e468eb62a26
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 24 14:14:25 2014 -0400
|
||||
|
||||
Refactored code to be more rigorous Unicode-wise.
|
||||
|
||||
M ActiveSync/NSString+ActiveSync.m
|
||||
M SoObjects/SOGo/NSString+Utilities.h
|
||||
M SoObjects/SOGo/NSString+Utilities.m
|
||||
M SoObjects/SOGo/SOGoGCSFolder.m
|
||||
|
||||
commit 1c60ab2337815b73ab651ac39f5465944c10e479
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 24 12:02:12 2014 -0400
|
||||
|
||||
Fix for bug #2889
|
||||
|
||||
M SOPE/NGCards/iCalTimeZone.m
|
||||
M SOPE/NGCards/iCalTimeZonePeriod.m
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit f4372af16d9479eecf0ec988a0081c5767f972e7
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 23 13:46:44 2014 -0400
|
||||
|
||||
Add over DAV a PARTSTAT if none is defined
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit 6ba85ee43aaa067f9ec13c05a7907c4eb72e7b98
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 22 11:38:07 2014 -0400
|
||||
|
||||
Added some comments in the code
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
|
||||
commit ae6afedc92acd2bd70f423cd24d21f9d7c47a104
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 22 08:38:01 2014 -0400
|
||||
|
||||
Fixed potential exception when Calendar module is disabled
|
||||
|
||||
M UI/WebServerResources/UIxPreferences.js
|
||||
|
||||
commit d572f2af0238304b11bbac54b0aa4636f49c30d5
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 19 14:34:20 2014 -0400
|
||||
|
||||
get rid of control chars before returning the response
|
||||
|
||||
M NEWS
|
||||
M SoObjects/SOGo/SOGoGCSFolder.m
|
||||
|
||||
commit a338b193ba0078d0a858b431d43f2e251fb29651
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 17 19:45:44 2014 -0400
|
||||
|
||||
Fix for bug #2838
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentFolders.m
|
||||
|
||||
commit 11adf388cf2b276356a6ab3051425442232f9992
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 17 11:51:46 2014 -0400
|
||||
|
||||
Cleaned the code and fixed #2894 while at it ...
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
M SoObjects/Mailer/SOGoDraftObject.m
|
||||
M SoObjects/Mailer/product.plist
|
||||
|
||||
commit a4ab2942e89c74915725aa51da4c25b2cc5b6049
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 17 11:35:09 2014 -0400
|
||||
|
||||
Fix for bugs #2878, #2879
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
|
||||
commit 7e281dca99b974d63e8d2b011459ab4335d54965
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Sep 17 09:45:44 2014 -0400
|
||||
|
||||
Fix encoding of calendar names in Web interface
|
||||
|
||||
M UI/WebServerResources/SchedulerUI.js
|
||||
|
||||
commit ce1896b6278d262da45f43f3612db60ab775a60a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 17 09:36:35 2014 -0400
|
||||
|
||||
Fixed typo
|
||||
|
||||
M Tests/Integration/README
|
||||
|
||||
commit f52a083326f053deb8ed9953a8dfe7363af00f3f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 17 09:34:36 2014 -0400
|
||||
|
||||
fixed sending mails to multiple recipients over AS
|
||||
|
||||
M ActiveSync/NGMimeMessage+ActiveSync.m
|
||||
M NEWS
|
||||
|
||||
commit 8ba031d6ec6a996cf8dc8fa53cd42866cf09f2df
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 15 19:54:07 2014 -0400
|
||||
|
||||
Consider 0x0C as "unsafe"
|
||||
|
||||
M SoObjects/SOGo/NSString+Utilities.m
|
||||
|
||||
commit c5c2bfb7a6117b00d563bf0230fb435b6026972d
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 15 14:08:54 2014 -0400
|
||||
|
||||
Fixed iCal detection for 10.9 (and perhaps even 10.8)
|
||||
|
||||
M SoObjects/Appointments/SOGoUserFolder+Appointments.h
|
||||
M SoObjects/Appointments/SOGoUserFolder+Appointments.m
|
||||
M SoObjects/SOGo/WORequest+SOGo.m
|
||||
|
||||
commit 6ec79f77924b7c9afb1967c4db415a66129cc313
|
||||
Author: Alexandre Cloutier <acloutier@inverse.ca>
|
||||
Date: Mon Sep 15 10:31:51 2014 -0400
|
||||
|
||||
bugfix with threads collapsing for a nested folder
|
||||
|
||||
M UI/MailerUI/UIxMailActions.m
|
||||
M UI/WebServerResources/MailerUI.js
|
||||
|
||||
commit 4b9db66f8b0bd0b18875fd29d81ec54d8bc517e1
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Sep 15 10:33:03 2014 -0400
|
||||
|
||||
Fix warning when generating docbook
|
||||
|
||||
M Documentation/Makefile
|
||||
|
||||
commit 02b3de6465c85e254f265cedb28a0e96aeef6f31
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 15 09:32:36 2014 -0400
|
||||
|
||||
Fix for bug #2326
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
M UI/Scheduler/UIxComponentEditor.m
|
||||
|
||||
commit 4b49fc33b257c8426071501aaf90de6e03c10f68
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Sun Sep 14 14:36:30 2014 +0200
|
||||
|
||||
Updated for 2.2.8
|
||||
|
||||
M Documentation/SOGoInstallationGuide.asciidoc
|
||||
M Documentation/docinfo.xml
|
||||
M Documentation/includes/global-attributes.asciidoc
|
||||
|
||||
commit 19b313e6c4488daebf053879076f09ab6df0b6ea
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Wed Sep 10 00:32:53 2014 +0200
|
||||
|
||||
Updated some copyright lines from PacketFence to SOGo
|
||||
|
||||
M Documentation/SOGoInstallationGuide.asciidoc
|
||||
M Documentation/docbook/xsl/headerfooter-fo.xsl
|
||||
M Documentation/docbook/xsl/sogo-fo-article.xsl
|
||||
M Documentation/docbook/xsl/sogo-fo.xsl
|
||||
M Documentation/docbook/xsl/titlepage-fo.xml
|
||||
M Documentation/docinfo.xml
|
||||
|
||||
commit 397d8d75741946ccb6d7e2d9751149dbad5a2be3
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Wed Sep 10 00:18:03 2014 +0200
|
||||
|
||||
Remove old documentation files
|
||||
|
||||
D Documentation/SOGo Installation Guide.odt
|
||||
D Documentation/SOGo Mobile Devices Configuration.odt
|
||||
D Documentation/SOGo Mozilla Thunderbird Configuration.odt
|
||||
D Documentation/SOGo Native Microsoft Outlook Configuration.odt
|
||||
D Documentation/architecture.png
|
||||
D Documentation/inverse.jpg
|
||||
D Documentation/openchange.png
|
||||
D Documentation/preferences.png
|
||||
D Documentation/sogo-2.png
|
||||
D Documentation/sogo.png
|
||||
|
||||
commit 8a564975c8fba678acb0bc7c5290131d4eb868ee
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Wed Sep 10 00:07:18 2014 +0200
|
||||
|
||||
Added makefile for asciidoc-conversion, included docbook-templates
|
||||
|
||||
M .gitignore
|
||||
A Documentation/Makefile
|
||||
D Documentation/SOGo Installation Guide.asciidoc
|
||||
D Documentation/SOGo Mobile Devices Configuration Guide.asciidoc
|
||||
D Documentation/SOGo Mozilla Thunderbird Configuration.asciidoc
|
||||
D Documentation/SOGo Native Outlook Configuration.asciidoc
|
||||
A Documentation/SOGoInstallationGuide.asciidoc
|
||||
A Documentation/SOGoMobileDevicesConfigurationGuide.asciidoc
|
||||
A Documentation/SOGoMozillaThunderbirdConfigurationGuide.asciidoc
|
||||
A Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc
|
||||
A Documentation/docbook/fop-centos6.patch
|
||||
A Documentation/docbook/xmlgraphics-fop-centos5.patch
|
||||
A Documentation/docbook/xsl/headerfooter-fo.xsl
|
||||
A Documentation/docbook/xsl/sogo-fo-article.xsl
|
||||
A Documentation/docbook/xsl/sogo-fo.xsl
|
||||
A Documentation/docbook/xsl/titlepage-fo.xml
|
||||
A Documentation/docbook/xsl/titlepage-fo.xsl
|
||||
A Documentation/docinfo.xml
|
||||
A Documentation/fonts/PALATINO.TTF
|
||||
A Documentation/fonts/deliciousitalic.ttf
|
||||
A Documentation/fonts/deliciousitalic.xml
|
||||
A Documentation/fonts/deliciousroman.ttf
|
||||
A Documentation/fonts/deliciousroman.xml
|
||||
A Documentation/fonts/fop-config.xml
|
||||
A Documentation/fonts/inconsolata.ttf
|
||||
A Documentation/fonts/inconsolata.xml
|
||||
A Documentation/fonts/oflgoudystm.ttf
|
||||
A Documentation/fonts/oflgoudystm.xml
|
||||
A Documentation/fonts/oflgoudystmitalic.ttf
|
||||
A Documentation/fonts/oflgoudystmitalic.xml
|
||||
A Documentation/fonts/palatino.xml
|
||||
A Documentation/images/inverse-logo.jpg
|
||||
A Documentation/images/sogo-logo.png
|
||||
|
||||
commit 95191cb29bbd14559e1d3ef5ee93865303e06859
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Sun Jul 20 00:22:38 2014 +0200
|
||||
|
||||
Added other documentation files as asciidoc
|
||||
|
||||
A Documentation/SOGo Mobile Devices Configuration Guide.asciidoc
|
||||
A Documentation/SOGo Mozilla Thunderbird Configuration.asciidoc
|
||||
A Documentation/SOGo Native Outlook Configuration.asciidoc
|
||||
A Documentation/images/openchange.png
|
||||
|
||||
commit 8d4c0ff6948fe40368d197e57b5fb2a22971e657
|
||||
Author: Jens Erat <email@jenserat.de>
|
||||
Date: Fri Jul 11 19:54:42 2014 +0200
|
||||
|
||||
Converted Installation Guide to asciidoc
|
||||
|
||||
A Documentation/SOGo Installation Guide.asciidoc
|
||||
A Documentation/images/architecture.png
|
||||
A Documentation/images/preferences-hierarchy.png
|
||||
A Documentation/includes/additional-info.asciidoc
|
||||
A Documentation/includes/commercial-support.asciidoc
|
||||
A Documentation/includes/global-attributes.asciidoc
|
||||
A Documentation/includes/license.asciidoc
|
||||
|
||||
commit 8b4a16df4ec7362e86a138d0761176a229a8304f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 12 14:10:22 2014 -0400
|
||||
|
||||
NEWS entry for previous commit
|
||||
|
||||
M NEWS
|
||||
|
||||
commit b8b3519a404ff26f3aadcf65e9c605998214a43c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 12 14:09:28 2014 -0400
|
||||
|
||||
Initial support for multiple alarms and better iCal compatibility
|
||||
|
||||
M ActiveSync/iCalEvent+ActiveSync.m
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
M SoObjects/Appointments/iCalEntityObject+SOGo.h
|
||||
M SoObjects/Appointments/iCalEntityObject+SOGo.m
|
||||
M UI/Scheduler/UIxAppointmentEditor.m
|
||||
M UI/Scheduler/UIxComponentEditor.m
|
||||
M UI/Scheduler/UIxTaskEditor.m
|
||||
|
||||
commit 12a4fd05a249cc6c0ea1f6c0722cbf50ce1afa39
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 12 08:34:15 2014 -0400
|
||||
|
||||
Support for repetitive alarms and tasks
|
||||
|
||||
M SOPE/GDLContentStore/GCSAlarmsFolder.m
|
||||
M SOPE/GDLContentStore/GCSFolder.m
|
||||
M SOPE/NGCards/CardElement.h
|
||||
M SOPE/NGCards/CardElement.m
|
||||
M SOPE/NGCards/iCalDateTime.m
|
||||
M SOPE/NGCards/iCalEvent.h
|
||||
M SOPE/NGCards/iCalRepeatableEntityObject.h
|
||||
M SOPE/NGCards/iCalRepeatableEntityObject.m
|
||||
M SOPE/NGCards/iCalToDo.m
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.h
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
M SoObjects/Appointments/SOGoAppointmentOccurence.h
|
||||
M SoObjects/Appointments/SOGoAppointmentOccurence.m
|
||||
M SoObjects/Appointments/SOGoComponentOccurence.h
|
||||
M SoObjects/Appointments/SOGoComponentOccurence.m
|
||||
M SoObjects/Appointments/SOGoEMailAlarmsManager.h
|
||||
M SoObjects/Appointments/SOGoEMailAlarmsManager.m
|
||||
M SoObjects/Appointments/SOGoTaskObject.m
|
||||
M SoObjects/Appointments/SOGoTaskOccurence.h
|
||||
M SoObjects/Appointments/SOGoTaskOccurence.m
|
||||
M SoObjects/Appointments/iCalCalendar+SOGo.m
|
||||
M SoObjects/Appointments/iCalEntityObject+SOGo.h
|
||||
M SoObjects/Appointments/iCalEntityObject+SOGo.m
|
||||
M SoObjects/Appointments/iCalEvent+SOGo.h
|
||||
M SoObjects/Appointments/iCalEvent+SOGo.m
|
||||
M SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.h
|
||||
M SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m
|
||||
M SoObjects/Appointments/iCalToDo+SOGo.h
|
||||
M SoObjects/Appointments/iCalToDo+SOGo.m
|
||||
M SoObjects/Contacts/NGVCard+SOGo.m
|
||||
M SoObjects/Contacts/NGVList+SOGo.m
|
||||
M Tools/SOGoEAlarmsNotifier.h
|
||||
M Tools/SOGoEAlarmsNotifier.m
|
||||
M UI/Scheduler/UIxAppointmentEditor.h
|
||||
M UI/Scheduler/UIxAppointmentEditor.m
|
||||
M UI/Scheduler/UIxCalListingActions.m
|
||||
M UI/Scheduler/UIxComponentEditor.h
|
||||
M UI/Scheduler/UIxComponentEditor.m
|
||||
M UI/Scheduler/UIxOccurenceDialog.m
|
||||
M UI/Scheduler/UIxTaskEditor.m
|
||||
M UI/Scheduler/product.plist
|
||||
M UI/WebServerResources/SchedulerUI.js
|
||||
M UI/WebServerResources/UIxTaskEditor.js
|
||||
|
||||
commit 0825a810e3f57339436a0ed912d003ce039e67a5
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Sep 11 11:58:39 2014 -0400
|
||||
|
||||
Add missing localization string
|
||||
|
||||
M UI/Common/English.lproj/Localizable.strings
|
||||
|
||||
commit ed85a09ff0467446cdcbbb5dc408f325ff6709ce
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Sep 11 11:55:20 2014 -0400
|
||||
|
||||
Allow alarms to be snoozed for 1 day
|
||||
|
||||
M NEWS
|
||||
M UI/WebServerResources/generic.js
|
||||
M Version
|
||||
|
||||
commit 38cb86bdb1520eec007c279151a41f75a60cc998
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 10 14:15:34 2014 -0400
|
||||
|
||||
Update ChangeLog
|
||||
|
||||
M ChangeLog
|
||||
|
||||
commit 69c8aa074364395a8bdf3705d74ee6a93c11d54a
|
||||
Author: Alexandre Cloutier <acloutier@inverse.ca>
|
||||
Date: Wed Sep 10 13:22:36 2014 -0400
|
||||
@@ -3021,6 +3525,18 @@ A UI/Templates/SchedulerUI/UIxCalViewPrint.wox
|
||||
M UI/Templates/UIxPageFrame.wox
|
||||
M UI/Templates/UIxToolbar.wox
|
||||
|
||||
commit b5dc2e264dda3f4f750a23d63a8b0fef70756655
|
||||
Author: Jeroen Dekkers <jeroen@dekkers.ch>
|
||||
Date: Thu Apr 10 00:33:05 2014 +0200
|
||||
|
||||
Link correctly against libraries used
|
||||
|
||||
Link the mapistore backend against libgnustep-base, libobjc,
|
||||
libNGObjWeb. Link the SAML code against gobject-2.0.
|
||||
|
||||
M OpenChange/GNUmakefile
|
||||
M configure
|
||||
|
||||
commit 49363cfe364ccf5add432f6375895ee283149dab
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Apr 11 21:37:55 2014 -0400
|
||||
@@ -3990,6 +4506,14 @@ Date: Tue Mar 18 19:06:41 2014 -0400
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
M ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m
|
||||
|
||||
commit 1c3f1af662910834c8c1e0af366f7e9260cb3e7b
|
||||
Author: Skruppy <skrupellos.spam@web.de>
|
||||
Date: Sat Mar 15 15:10:26 2014 +0100
|
||||
|
||||
ModulesConstraints tests all values of a multi-valued attributes
|
||||
|
||||
M SoObjects/SOGo/LDAPSource.m
|
||||
|
||||
commit e2f192b7935f8ca316737db39372a3ab49479e83
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Mar 14 15:45:12 2014 -0400
|
||||
@@ -8796,6 +9320,14 @@ Date: Mon Apr 15 14:13:07 2013 -0400
|
||||
|
||||
M OpenChange/MAPIStoreContactsMessage.m
|
||||
|
||||
commit 4d8bff51300c4a84332e54035bf3389949ed034d
|
||||
Author: Jeroen Dekkers <jeroen@dekkers.ch>
|
||||
Date: Mon Mar 11 19:37:45 2013 +0100
|
||||
|
||||
Link libSOGo with libdl on systems with glibc
|
||||
|
||||
M SoObjects/SOGo/GNUmakefile.preamble
|
||||
|
||||
commit 3cd91846a633057e27d476cd0a6cc7e1d499dc1f
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Apr 11 16:32:17 2013 -0400
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
all: $(patsubst %.asciidoc,%.pdf,$(wildcard *.asciidoc))
|
||||
|
||||
%.pdf : %.asciidoc
|
||||
asciidoc -a docinfo1 -b docbook -d book -d book -o $<.docbook $<
|
||||
fop -c fonts/fop-config.xml -xsl docbook/xsl/sogo-fo.xsl -xml $<.docbook -pdf $@
|
||||
|
||||
clean:
|
||||
rm *.asciidoc.docbook *.pdf
|
||||
@@ -0,0 +1,330 @@
|
||||
Mobile Devices Configuration Guide
|
||||
==================================
|
||||
|
||||
////
|
||||
|
||||
This file is part of the SOGo project.
|
||||
|
||||
See SOGo Mobile Devices Configuration-docinfo.xml for authors,
|
||||
copyright and license information.
|
||||
|
||||
////
|
||||
|
||||
include::includes/global-attributes.asciidoc[]
|
||||
|
||||
About this Guide
|
||||
----------------
|
||||
|
||||
This guide will walk you through the installation and configuration of
|
||||
popular SyncML clients to be used with the SOGo solution.
|
||||
|
||||
This guide also include instructions for configuring Apple iPhone OS
|
||||
devices (iPhone, iPod touch, and iPad).
|
||||
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available at
|
||||
http://www.sogo.nu/downloads/documentation.html.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
SOGo is a free and modern scalable groupware server. It offers shared
|
||||
calendars, address books, and emails through your favourite Web browser
|
||||
and by using a native client such as Mozilla Thunderbird and Lightning.
|
||||
|
||||
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
|
||||
and iTIP and reuses existing IMAP, SMTP and database servers - making
|
||||
the solution easy to deploy and interoperable with many applications.
|
||||
|
||||
SOGo features:
|
||||
|
||||
* Scalable architecture suitable for deployments from dozen to many
|
||||
thousand users
|
||||
* Rich Web-based interface that shares the look and feel, the features
|
||||
and the data of Mozilla Thunderbird and Lightning
|
||||
* Improved integration with Mozilla Thunderbird and Lighthing by using
|
||||
the SOGo Connector and the SOGo Integrator
|
||||
* Two-way synchronization support with any Microsoft ActiveSync-capable
|
||||
device, or Outlook 2013
|
||||
|
||||
SOGo is developed by a community of developers located mainly in North
|
||||
America and Europe. More information can be found on
|
||||
http://www.sogo.nu/.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
This section will guide you through the installation of popular SyncML
|
||||
clients on various devices.
|
||||
|
||||
Funambol SyncML Client
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The recommended SyncML client for BlackBerry, Apple iPhone (for
|
||||
contacts), mobile devices based on Microsoft Windows Mobile Smartphone
|
||||
or Windows Mobile PocketPC, is the one provided directly by Funambol,
|
||||
which is free and open source.
|
||||
|
||||
For Microsoft Window Mobile, you must identify which kind of device you
|
||||
have ("Smartphone" vs. "PocketPC").
|
||||
|
||||
Once you've identified what kind of device you have, download the
|
||||
appropriate client from:
|
||||
|
||||
http://www.funambol.com/opensource/downloads.php
|
||||
|
||||
The version 8.5 GA or later is required.
|
||||
|
||||
NextHaus SyncJe
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
For BlackBerry and Apple iPhone devices, you can also use the
|
||||
SyncJe SyncML client from NextHaus (http://www.nexthaus.com/). This
|
||||
client allows one to synchronize contacts, event and tasks with SOGo.
|
||||
|
||||
The version 2.43 or later is required. For BlackBerry 7XXX devices, the
|
||||
required version is 2.25 but isn't officially supported. You can install
|
||||
SyncJe on your BlackBerry device, over the air, by opening the following
|
||||
link from your BlackBerry device:
|
||||
|
||||
http://www.nexthaus.com/bb/syncjebb.jad
|
||||
|
||||
This will download and install the application on your mobile device.
|
||||
It's important to use the Web browser application and not the WAP
|
||||
browser to perform this operation. Once installed, restart the device.
|
||||
This procedure can also be used to update the SyncJe application. Note
|
||||
that an update of SyncJe will not affect the state of previous
|
||||
synchronizations. It's not necessary to perform a "slow sync" after an
|
||||
update of SyncJe.
|
||||
|
||||
Synthesis SyncML Client
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Synthesis (http://www.synthesis.ch/) company provides a SyncML
|
||||
client for Palm OS-based devices.
|
||||
|
||||
"Over The Air" synchronization is possible, as well as synchronization
|
||||
through a cradle. For the latter, you must install Softick PPP using the
|
||||
Palm Desktop software. The version 3.01 or later is required and you can
|
||||
download it from http://www.softick.com/ppp/. Once installed, the
|
||||
desktop computer must be restarted.
|
||||
|
||||
Once completed, you must download the Synthesis client for Palm OS. The
|
||||
version 3.0.2.9 or later is required. Either the standard or the
|
||||
professional version can be used.
|
||||
|
||||
Once downloaded, uncompress the archive and install the `.prc` file on
|
||||
your Palm OS-based device. After, you should see a "SyncML" icon on your
|
||||
device.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
In this section, you'll learn how to configure the popular SyncML
|
||||
clients in order to fully synchronize your mobile device with SOGo.
|
||||
|
||||
Instructions for Apple iPhone OS based devices are also included. Note
|
||||
that those devices do not require a SyncML client for synchronizing
|
||||
calendars.
|
||||
|
||||
Funambol SyncML Client
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the Funambol SyncML client is installed, start the application from
|
||||
your mobile device to configure it using the following steps:
|
||||
|
||||
From the _Tools_ menu, choose _Options..._:
|
||||
|
||||
* Specify the _Location_. If your SOGo server is `sogo.domain.com`, the
|
||||
location should be `http://sogo.domain.com/funambol/ds`.
|
||||
* Specify your username and password
|
||||
* Check the _Contacts_ check box and click on the _Details_ button.
|
||||
The synchronization type is _two-way_ and the _Remote name_ is
|
||||
`sogo-card`. The data format is vCard.
|
||||
* Check the _Calendar_ check box and click on the _Details_ button. The
|
||||
synchronization type is _two-way_ and the _Remote name_ is `sogo-cal`.
|
||||
The data format is vCalendar.
|
||||
* Check the _Tasks_ check box and click on the _Details_ button. The
|
||||
synchronization type is _two-way_ and the _Remote name_ is
|
||||
`sogo-todo`. The data format is SIF.
|
||||
* Save the preferences.
|
||||
|
||||
To prevent the BlackBerry to automatically add a new event in the
|
||||
calendar when an invitation is received by email (IMIP message) on the
|
||||
BlackBerry device, you should delete the CICAL service from the Service
|
||||
Book. To do so, proceed with the following steps:
|
||||
|
||||
From the _Options_ menu:
|
||||
|
||||
* Choose _Advanced Options_
|
||||
* Choose _Service Book_
|
||||
* Identify the line that mentions the email address of the BlackBerry
|
||||
user followed by the `[CICAL]` string. For example, `user@domain.com
|
||||
[CICAL]`.
|
||||
* Delete this entry.
|
||||
|
||||
Once completed, you must restart the device by removing its battery for
|
||||
a couple of seconds. If you ever want to reactivate the CICAL service,
|
||||
follow those instructions:
|
||||
|
||||
http://support.appriver.com/KB/a205/how-to-resend-service-books-on-blackberry.aspx
|
||||
|
||||
Once complete, the client is ready for an initial synchronization.
|
||||
|
||||
Ideally, you should *delete* all data from the mobile device before the
|
||||
initial synchronization. To do so:
|
||||
|
||||
* From the _Tools_ menu, choose _Recover..._
|
||||
* Choose _Replace with data from server_
|
||||
* Check the _Contacts_, _Calendar_ and _Tasks_ check boxes
|
||||
|
||||
Finally, click on the _Sync All_ button to proceed with the
|
||||
synchronization.
|
||||
|
||||
NextHaus SyncJe
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Once NextHaus SyncJe is installed, proceed with the following steps,
|
||||
from your BlackBerry device, to configure it:
|
||||
|
||||
* Open the _SyncJe Client_
|
||||
|
||||
From the _Settings_ menu:
|
||||
|
||||
* Specify the _Server URL_. If your SOGo server is `sogo.domain.com`,
|
||||
the URL should be `http://sogo.domain.com/funambol/ds`.
|
||||
* Specify your user name and password
|
||||
* Check the _Contacts_ check box and specify `sogo-card` as the
|
||||
_Foldername_
|
||||
* Check the _Calendar_ check box and specify `sogo-cal` as the
|
||||
_Foldername_
|
||||
* Check the _ToDo_ check box and specify `sogo-todo` as the _Foldername_
|
||||
* Check the _Auto Sync_ check box if you wish to automatically
|
||||
synchronize contacts, events and tasks at a predefined time interval
|
||||
* Do *not* check the _Sync events between_ check box
|
||||
* Check the _Skip saving attendees_ - this will prevent the BlackBerry
|
||||
device from sending emails to meeting participants for events
|
||||
downloaded from the SOGo server
|
||||
* Check the _BIS_ check box (for _BlackBerry Internet Services_)
|
||||
* Leave the other fields to the their default value
|
||||
* Then choose _Save_ from the menu to save the preferences
|
||||
|
||||
To prevent the BlackBerry to automatically add a new event in the
|
||||
calendar when an invitation is received by email (IMIP message) on the
|
||||
BlackBerry device, you should delete the CICAL service from the Service
|
||||
Book. To do so, proceed with the following steps:
|
||||
|
||||
From the _Options_ menu:
|
||||
|
||||
* Choose _Advanced Options_
|
||||
* Choose _Service Book_
|
||||
* Identify the line that mentions the email address of the BlackBerry
|
||||
user followed by the `[CICAL]` string. For example, `user@domain.com
|
||||
[CICAL]`.
|
||||
* Delete this entry
|
||||
|
||||
Once completed, you must restart the device by removing its battery for
|
||||
a couple of seconds. If you ever want to reactivate the CICAL service,
|
||||
follow those instructions:
|
||||
|
||||
http://support.appriver.com/KB/a205/how-to-resend-service-books-on-blackberry.aspx
|
||||
|
||||
Once done, you're now ready for your first synchronization.
|
||||
|
||||
Ideally, you must delete all data on the BlackBerry before proceeding
|
||||
with the initial synchronization. To do so, proceed with the following
|
||||
steps:
|
||||
|
||||
* Open the _SyncJe Client_
|
||||
|
||||
From the _Settings_ menu:
|
||||
|
||||
* Choose the _Clear databases_ option
|
||||
* Respond _Yes_ to all questions. This will delete all contacts, events
|
||||
and tasks from your BlackBerry device.
|
||||
* Go back in the previous menu
|
||||
* Choose the _Force Slow Sync_ option
|
||||
* Choose the _Start Sync_ option to start the synchronization. This
|
||||
could take a few minutes if you have many contacts, events or tasks.
|
||||
Subsequent synchronizations should be much faster.
|
||||
|
||||
After the initial _Slow Sync_, you can simply chose the _Start Sync_
|
||||
option if you do a manual synchronization to synchronize all changes.
|
||||
|
||||
Synthesis SyncML Client
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the Synthesis SyncML client is installed, proceed with the
|
||||
following steps to configure it:
|
||||
|
||||
* Open the _Synthesis SyncML Standard Edition_ application
|
||||
|
||||
From the _Settings..._ menu:
|
||||
|
||||
* Specify the _Server URL_. If your SOGo server is `sogo.domain.com`,
|
||||
the URL should be `http://sogo.domain.com/funambol/ds`.
|
||||
* Specify your user name and password
|
||||
* Check the _Contacts_, _Events_ and _Task_ check boxes
|
||||
* Click on the _more..._ button
|
||||
* For the _Contacts_, choose _reload device_ and specify `sogo-card` as
|
||||
the _Server Path_.
|
||||
* For the _Events_, choose _reload device_ and specify `sogo-cal` as
|
||||
the _Server Path_. Do *not* check the _Only from..._ check box.
|
||||
* For the _Tasks_, choose _reload device_ and specify `sogo-todo` as
|
||||
the _Server Path_.
|
||||
* Once completed, click on the _Done_ button
|
||||
|
||||
The _reload device_ value will *delete* all entries on the device during
|
||||
the initial synchronization and obtain contacts, events and tasks from
|
||||
the server. If you do not want to delete everything from the device,
|
||||
please choose _normal_ instead of _reload device_.
|
||||
|
||||
Once ready, click on the _Start_ button to proceed with the initial
|
||||
synchronization.
|
||||
|
||||
During the initial synchronization, the Palm device will ask you how to
|
||||
connect to the desktop system. From the Palm device, choose _Windows
|
||||
RAS_ without specifying an user name or a password. This will allow the
|
||||
Palm device to establish a PPP connection between itself and Softick PPP
|
||||
and then communicate using its TCP/IP stack to the Funambol server.
|
||||
|
||||
Apple iOS — Calendars
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Starting from iOS 3, Apple has added CalDAV support to the calendar
|
||||
application included in the iPhone/iPod/iPad.
|
||||
|
||||
To add a CalDAV account, follow those instructions:
|
||||
|
||||
* From the _Settings_ menu, choose _Mail, Contacts, Calendars_
|
||||
* Choose _Add Account..._
|
||||
* Choose _Other_
|
||||
* Choose _Add CalDAV Account_
|
||||
* Specify the _Server_, the URL should be
|
||||
`http://sogo.domain.com/SOGo/dav/<username>`
|
||||
|
||||
On iOS 3.1.2 and later, you must also specify the range of events you
|
||||
want to have.
|
||||
|
||||
* From the _Settings_ menu, choose _Mail, Contacts, Calendars_
|
||||
* From the _Sync_ menu, choose _All Events_
|
||||
|
||||
Note that other options (_Events 2 Weeks Back_, etc.) do not work right
|
||||
now.
|
||||
|
||||
Apple iOS — Contacts
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to synchronize contacts with your Apple mobile device, use
|
||||
the native address book application with SOGo using the CardDAV
|
||||
protocol. To configure the address book application so it works with
|
||||
SOGo, create a new CardDAV account and specify your server name. In
|
||||
the _Advanced Settings_, set the port to `8800`.
|
||||
|
||||
On iOS prior to version 4, you must install the Funambol client and
|
||||
configure the `sogo-card` source.
|
||||
|
||||
include::includes/additional-info.asciidoc[]
|
||||
|
||||
include::includes/commercial-support.asciidoc[]
|
||||
@@ -0,0 +1,358 @@
|
||||
Mozilla Thunderbird Configuration Guide
|
||||
=======================================
|
||||
|
||||
////
|
||||
|
||||
This file is part of the SOGo project.
|
||||
|
||||
See SOGo Mozilla Thunderbird Configuration Guide-docinfo.xml for
|
||||
authors, copyright and license information.
|
||||
|
||||
////
|
||||
|
||||
include::includes/global-attributes.asciidoc[]
|
||||
|
||||
About this Guide
|
||||
----------------
|
||||
|
||||
This guide will walk you through the installation and configuration of
|
||||
Mozilla Thunderbird and its associated extensions so it can be used with
|
||||
the SOGo solution.
|
||||
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available
|
||||
at http://www.sogo.nu/downloads/documentation.html.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
SOGo is a free and modern scalable groupware server. It offers shared
|
||||
calendars, address books, and emails through your favourite Web browser
|
||||
and by using a native client such as Mozilla Thunderbird and Lightning.
|
||||
|
||||
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
|
||||
and iTIP and reuses existing IMAP, SMTP and database servers - making
|
||||
the solution easy to deploy and interoperable with many applications.
|
||||
|
||||
SOGo features:
|
||||
|
||||
* Scalable architecture suitable for deployments from dozen to many
|
||||
thousand users
|
||||
* Rich Web-based interface that shares the look and feel, the features
|
||||
and the data of Mozilla Thunderbird and Lightning
|
||||
* Improved integration with Mozilla Thunderbird and Lightning by using
|
||||
the SOGo Connector and the SOGo Integrator extensions
|
||||
* Two-way synchronization support with any Microsoft ActiveSync-capable
|
||||
device, or Outlook 2013
|
||||
|
||||
SOGo is developed by a community of developers located mainly in North
|
||||
America and Europe. More information can be found on
|
||||
http://www.sogo.nu/.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
This section will guide you through the installation of Thunderbird and
|
||||
its associated extensions.
|
||||
|
||||
Mozilla Thunderbird
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mozilla Thunderbird is the official front end client of SOGo.
|
||||
|
||||
Mozilla Thunderbird version 2, 3.1, 10 ESR (Extended Support Release),
|
||||
17 ESR, 24 and 31 are supported and it is recommended to use version 31 of
|
||||
Thunderbird.
|
||||
|
||||
In order to download and install Mozilla Thunderbird, please visit:
|
||||
|
||||
https://www.mozilla.org/en-US/thunderbird/organizations/all-esr.html
|
||||
|
||||
Mozilla Lightning
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
When using version 24 or 31 of Thunderbird, you can use the latest version of
|
||||
Mozilla Lightning. Use the Add-ons manager of Thunderbird or visit:
|
||||
|
||||
https://addons.mozilla.org/en-US/thunderbird/addon/lightning/
|
||||
|
||||
When using version 17 ESR of Thunderbird, you can use Mozilla Lightning
|
||||
version 1.9.1. In order to download the extension, please visit:
|
||||
|
||||
https://addons.mozilla.org/en-US/thunderbird/addon/lightning/versions/?page=1#version-1.9.1
|
||||
|
||||
For Thunderbird 2 and 3.1, you need the _Inverse Edition_of Mozilla
|
||||
Lightning. It provides back ported features, bug fixes and security
|
||||
fixes from the current development version of Mozilla Lightning. For
|
||||
Thunderbird 2, it is based on release version 0.9 of Lightning. For
|
||||
Thunderbird 3.1, it is based on 1.0b2.
|
||||
|
||||
In order to download and install Mozilla Lightning – Inverse Edition for
|
||||
Thunderbird 2 or 3.1, please visit:
|
||||
|
||||
http://www.sogo.nu/downloads/frontends.html
|
||||
|
||||
SOGo Connector and SOGo Integrator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The SOGo Connector and Integrator extensions are provided to perfect the
|
||||
integration of Mozilla Thunderbird 2, 3.1, 10 ESR, 17 ESR, 24 and 31 with
|
||||
the SOGo groupware solution.
|
||||
|
||||
First of all, the SOGo Connector extension transforms Thunderbird into a
|
||||
full DAV client for groupware servers such as SOGo, eGroupware or
|
||||
Citadel. It does this by adding support for remote DAV address books and
|
||||
by adding features to be used along with the Lightning calendar
|
||||
extension.
|
||||
|
||||
Among supported features of the SOGo Connector extension, we have:
|
||||
|
||||
* Free / Busy URL field in the address book
|
||||
* Free / Busy functionality through HTTP
|
||||
* Event organizers
|
||||
* Synchronization of the address book using GroupDAV
|
||||
* CardDAV implementation for the address book
|
||||
* Support for WebDAV ACL
|
||||
|
||||
On the other hand, the SOGo Integrator extension transforms Thunderbird
|
||||
into a pure "heavy" client for SOGo. Whereas the SOGo Connector is meant
|
||||
for portability (horizontal integration), the SOGo Integrator makes use
|
||||
of the features and layout only available from SOGo (vertical
|
||||
integration).
|
||||
|
||||
Among the supported features of the SOGo Integrator extension, we have :
|
||||
|
||||
* Remote administration of folder subscriptions
|
||||
* Remote administration of folder access control lists (ACL)
|
||||
* Automatic replication of your local and subscribed folders
|
||||
* When correctly configured, it handles the propagation of updates to
|
||||
chosen extensions from a local update server
|
||||
* Automatic propagation of default settings
|
||||
|
||||
In order to download and install the SOGo Connector and Integrator
|
||||
extensions, please visit:
|
||||
|
||||
http://www.sogo.nu/downloads/frontends.html
|
||||
|
||||
Prior to installing the SOGo Integrator extension, you should read the
|
||||
following chapter – _SOGo Integrator Customization_.
|
||||
|
||||
SOGo Integrator Customization
|
||||
-----------------------------
|
||||
|
||||
In this section, you'll learn how to customize the SOGo Integrator
|
||||
extension so it can be used alongside your SOGo server.
|
||||
|
||||
Customization
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The customization steps described here involves understanding of XML and
|
||||
of text file edition. If you do not have those skills, it is recommended
|
||||
that you don't try to use this extension.
|
||||
|
||||
There are actually two steps in the configuration of a working
|
||||
environment for SOGo Integrator. First of all, the Integrator will use
|
||||
the same user name used to connect to the first email server configured
|
||||
in Thunderbird. It is a current limitation but it will fit nearly all
|
||||
configurations out there.
|
||||
|
||||
For testing purpose, you are strongly recommended to create and
|
||||
configure an additional user profile for Thunderbird. This is for two
|
||||
reasons. The first is because of the limitation mentioned above. The
|
||||
second is because the Integrator will synchronize your personal address
|
||||
book onto the SOGo server and then remove it so that only your personal
|
||||
address book on SOGo will be available. If you are not able to do that,
|
||||
you may want to make a copy of that address book beforehand.
|
||||
|
||||
The second part requires editing one file in the extension file sub tree
|
||||
to specify where the SOGo server is located. This is done by hand. In an
|
||||
enterprise environment, this step is only required once per release
|
||||
since the updates are expected to propagate automatically.
|
||||
|
||||
Uncompress (using a ZIP or jar tool) the SOGo Integrator XPI and locate
|
||||
the following file:
|
||||
|
||||
extensions.rdf
|
||||
|
||||
This file is used for locating the extension update server and the SOGo
|
||||
server, which we consider to be the same for the moment. There is a line
|
||||
starting with a "Seq" tag and with an attribute named "isi:updateURL".
|
||||
Replace the host part of that url with the SOGo server you want to
|
||||
connect to.
|
||||
|
||||
For example, one would replace:
|
||||
|
||||
<Seq about="http://inverse.ca/sogo-integrator/extensions" isi:updateURL="http://sogo-demo.inverse.ca/plugins/updates.php?plugin=%ITEM_ID%&version=%ITEM_VERSION%&platform=%PLATFORM%">
|
||||
|
||||
by:
|
||||
|
||||
<Seq about="http://inverse.ca/sogo-integrator/extensions" isi:updateURL="https://sogo.acme.com/plugins/updates.php?plugin=%ITEM_ID%&version=%ITEM_VERSION%&platform=%PLATFORM%">
|
||||
|
||||
if the SOGo server is accessible from the following URL:
|
||||
|
||||
https://sogo.acme.com/SOGo
|
||||
|
||||
Note that if you changed the `x-webobjects-server-url` configuration
|
||||
setting from your HTTP server configuration file for SOGo, the
|
||||
value *must* match the one you specify in `isi:updateURL` – even the
|
||||
port number.
|
||||
|
||||
Moreover, you *must* change the value of the
|
||||
`sogo-integrator.autocomplete.server.urlid` preference from
|
||||
`defaults/preferences/site.js` to match the identifier of your
|
||||
_SOGoUserSources_. This source will be used by Thunderbird for
|
||||
autocompletion.
|
||||
|
||||
Once you're done modifying the configuration file, save your changes and
|
||||
reconstruct the XPI file.
|
||||
|
||||
Now start Thunderbird and install your newly modified extension.
|
||||
|
||||
SOGo Update Server
|
||||
------------------
|
||||
|
||||
In this section, you will learn how to install and configure the SOGo
|
||||
Update Server.
|
||||
|
||||
The SOGo Update Server can be used to automatically install or uninstall
|
||||
Mozilla Thunderbird extensions, push user settings and more – all from a
|
||||
central place managed by system administrators.
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Installation is relatively straightforward. You need to make
|
||||
the `updates.php` script available through your HTTP server at the URL
|
||||
you've specified from the `extensions.rdf` file. The `updates.php`
|
||||
script can be found in the SOGo sources, under the `Scripts` directory.
|
||||
|
||||
The `updateLink` section of the XML payload returned to sogo-integrator
|
||||
is built dynamically using the `SCRIPT_URI` variable, which is only
|
||||
available when running with mod_rewrite. It should work out of the box
|
||||
as long as the script is placed in the same directory as the xpi files.
|
||||
|
||||
If it is not the case, then the link should be adjusted to fit the
|
||||
actual file layout:
|
||||
|
||||
<em:updateLink><?php echo dirname(getenv('SCRIPT_URI')) . '/relative/path/to/' . $plugin["filename"] ?></em:updateLink>
|
||||
|
||||
An http request similar to the following can be used to make sure that
|
||||
the generated link is correct:
|
||||
|
||||
http://sogo.host/path/to/updates.php?plugin=sogo-integrator@inverse.ca&version=0.00
|
||||
|
||||
Please refer to your HTTP server documentation for the installation and
|
||||
configuration of PHP.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
To configure the SOGo update server, you need to modify the
|
||||
`updates.php` script directly.
|
||||
|
||||
Adding an extension to be pushed automatically by the update server
|
||||
require you to modify the `$plugins` array from updates.php and also
|
||||
adjust accordingly SOGo Integrator's `extensions.rdf` file.
|
||||
|
||||
For example, to automatically install SOGo Connector, SOGo Integrator
|
||||
and Lightning, you would have:
|
||||
|
||||
----
|
||||
$plugins
|
||||
= array( "sogo-connector@inverse.ca"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "31.0.0",
|
||||
"filename" => "sogo-connector-31.0.0.xpi" ),
|
||||
"sogo-integrator@inverse.ca"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "31.0.0",
|
||||
"filename" => "sogo-integrator-31.0.0-sogo-demo.xpi" ),
|
||||
"{e2fda1a4-762b-4020-b5ad-a41df1933103}"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "3.3.1",
|
||||
"filename" => "lightning.xpi" ));
|
||||
----
|
||||
|
||||
The syntax is:
|
||||
|
||||
----
|
||||
"<extension ID>"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "<exact version found in the extension's install.rdf file>",
|
||||
"filename" => "<exact filename on the filesystem>" )
|
||||
----
|
||||
|
||||
The path of the filename, specified in the `filename` parameter, is
|
||||
relative to the location of the `updates.php` script. For extensions
|
||||
that are dependant on the architecture and operating system (Microsoft
|
||||
Windows, Apple Mac OS X, etc.), they can be placed in subdirectories
|
||||
relative again to the `updates.php` script (but the filename must be
|
||||
identical in all subdirectories). For exemple, for Mozilla Lightning, we
|
||||
could have:
|
||||
|
||||
----
|
||||
Darwin_x86-gcc3/lightning.xpi
|
||||
Linux_x86-gcc3/lightning.xpi
|
||||
Linux_x86_64-gcc3/lightning.xpi
|
||||
WINNT_x86-msvc/lightning.xpi
|
||||
----
|
||||
|
||||
If you eventually want to disable an extension, that is, without
|
||||
removing it from your users' computers, you can specify `disabled` as
|
||||
the version number.
|
||||
|
||||
Next is to modify the `extensions.rdf` file. Again, to automatically
|
||||
install SOGo Connector, SOGo Integrator and Lightning, you would have:
|
||||
|
||||
----
|
||||
<li>
|
||||
<Description
|
||||
em:id="{e2fda1a4-762b-4020-b5ad-a41df1933103}"
|
||||
em:name="Lightning"/>
|
||||
</li>
|
||||
<li>
|
||||
<Description
|
||||
em:id="sogo-integrator@inverse.ca"
|
||||
em:name="SOGo Integrator"/>
|
||||
</li>
|
||||
<li>
|
||||
<Description
|
||||
em:id="sogo-connector@inverse.ca"
|
||||
em:name="SOGo Connector"/>
|
||||
</li>
|
||||
----
|
||||
|
||||
Using SOGo Integrator, you can also push user-settings for any part of
|
||||
Thunderbird or its extensions. There are two kind of user-settings
|
||||
push:
|
||||
|
||||
* Settings that are pushed during the initial configuration of
|
||||
Thunderbird
|
||||
* Settings that are pushed upon every restart (ie., forced) of
|
||||
Thunderbird
|
||||
|
||||
Settings that pushed are pushed during initial configuration are
|
||||
controlled by the `./defaults/preferences/site.js` file from SOGo
|
||||
Integrator. Here is an example:
|
||||
|
||||
----
|
||||
pref("calendar.alarms.showmissed", false);
|
||||
pref("calendar.caldav.sched.enabled", true);
|
||||
----
|
||||
|
||||
Preferences that are forced upon every restart of Thunderbird are
|
||||
controlled from the `./chrome/content/general/custom-preferences.js`
|
||||
configuration file.
|
||||
|
||||
Here is an example:
|
||||
|
||||
----
|
||||
force_int_pref("changequote.replyformat.format", 0);
|
||||
force_bool_pref("changequote.headers.withcc", true);
|
||||
force_char_pref(“foo.bar”, “zot”);
|
||||
----
|
||||
|
||||
include::includes/additional-info.asciidoc[]
|
||||
|
||||
include::includes/commercial-support.asciidoc[]
|
||||
@@ -0,0 +1,691 @@
|
||||
Native Microsoft Outlook Configuration Guide
|
||||
============================================
|
||||
|
||||
////
|
||||
|
||||
This file is part of the SOGo project.
|
||||
|
||||
See SOGo Native Microsoft Outlook Configuration-docinfo.xml for
|
||||
authors, copyright and license information.
|
||||
|
||||
////
|
||||
|
||||
include::includes/global-attributes.asciidoc[]
|
||||
|
||||
About this Guide
|
||||
----------------
|
||||
|
||||
This guide will walk you through the installation and configuration of
|
||||
the native Microsoft Outlook compatibility layer SOGo offers.
|
||||
|
||||
Prior going over this guide, you should have a working SOGo
|
||||
installation. Please refer to the _SOGo Installation and Configuration
|
||||
Guide_ for more information on installing and configuring SOGo.
|
||||
|
||||
This guide also includes instructions for configuring Microsoft Outlook
|
||||
with SOGo.
|
||||
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available
|
||||
at http://www.sogo.nu/downloads/documentation.html.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
SOGo is a free and modern scalable groupware server. It offers shared
|
||||
calendars, address books, and emails through your favourite Web browser
|
||||
and by using a native client such as Mozilla Thunderbird and Lightning.
|
||||
|
||||
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
|
||||
and iTIP and reuses existing IMAP, SMTP and database servers — making
|
||||
the solution easy to deploy and interoperable with many applications.
|
||||
|
||||
SOGo features:
|
||||
|
||||
* Scalable architecture suitable for deployments from dozen to many
|
||||
thousand users
|
||||
* Rich Web-based interface that shares the look and feel, the features
|
||||
and the data of Mozilla Thunderbird and Lightning
|
||||
* Improved integration with Mozilla Thunderbird and Lightning by using
|
||||
the SOGo Connector and the SOGo Integrator
|
||||
* Native compatibility for Microsoft Outlook 2003, 2007, 2010, and 2013
|
||||
* Two-way synchronization support with any Microsoft ActiveSync-capable
|
||||
device, and Outlook 2013
|
||||
|
||||
SOGo is developed by a community of developers located mainly in North
|
||||
America and Europe. More information can be found
|
||||
on http://www.sogo.nu/.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
The following diagram demonstrates the architecture of the native
|
||||
Outlook compatibility layer of SOGo.
|
||||
|
||||
image::images/openchange.png[]
|
||||
|
||||
With Samba 4 and OpenChange, Microsoft Outlook clients can communicate
|
||||
natively with SOGo using the Microsoft Exchange protocol, without
|
||||
requiring costly and hard-to-maintain third-party MAPI connectors for
|
||||
Microsoft Outlook.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Organizations generally have solutions to authenticate users such as
|
||||
LDAP servers or Microsoft Active Directory servers.
|
||||
|
||||
The solution being used will influence how users are provisioned in
|
||||
Samba 4, a key component for native Outlook compatibility in SOGo.
|
||||
|
||||
LDAP Server
|
||||
~~~~~~~~~~~
|
||||
|
||||
If your organization uses a LDAP server such OpenLDAP, Novell
|
||||
eDirectory, Apache Directory or any other solution, you must use
|
||||
Samba 4's internal directory server and synchronize the data between
|
||||
both.
|
||||
|
||||
Synchronization scripts are not provided and unless you have clear-text
|
||||
passwords of your existing users, they will have to be changed during
|
||||
your initial synchronization so that your LDAP's server passwords are
|
||||
identical to the ones from Samba 4.
|
||||
|
||||
Any modifications to your existing LDAP server (password change, user
|
||||
addition or deletion, etc.) will have to be replicated to Samba 4's
|
||||
internal directory server.
|
||||
|
||||
Note that if you install Samba 4 on a server that is already running a
|
||||
LDAP service, you will have to change to TCP port on which your LDAP
|
||||
server listens to. Samba 4 will use the TCP port 389 and it can't be
|
||||
changed.
|
||||
|
||||
For example, with OpenLDAP, you can use the `-h` parameter for `slapd`
|
||||
to make it listen on an other TCP port.
|
||||
|
||||
Microsoft Active Directory
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If your organization uses Microsoft Active Directory, Samba 4 will need
|
||||
to be joined to your Active Directory domain, as a DC.
|
||||
|
||||
Samba 4 will be able to reuse all the information contained in Microsoft
|
||||
Active Directory and no synchronization process needs to be put in place
|
||||
as information will get replicated to Samba 4 automatically.
|
||||
|
||||
For more information on joining Samba 4 to an existing Microsoft Active
|
||||
Directory domain, please refer to the Samba 4 documentation available at
|
||||
the following URL:
|
||||
|
||||
http://wiki.samba.org/index.php/Samba4
|
||||
|
||||
More specifically, have a look at the `samba-tool domain join` command.
|
||||
Note that joining Samba 4 to your Active Directory domain as a member
|
||||
will currently not work. An authentication bug is present in Samba 4
|
||||
which then prevents all Outlook users to successfully authenticate
|
||||
through Samba 4. This issue has been reported to the Samba team and is
|
||||
being worked on.
|
||||
|
||||
Other or No Solution
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If your organization neither uses a LDAP server or Microsoft Active
|
||||
Directory, you can start using Samba 4 as your directory server.
|
||||
|
||||
Samba 4's directory can be queried over LDAP just like Microsoft Active
|
||||
Directory and can also serve as a domain controller for Windows-based
|
||||
environments.
|
||||
|
||||
For example, SOGo can very well use Samba 4's built-in directory server
|
||||
to authenticate users. A SOGoUserSources entry to achieve this wold look
|
||||
like this:
|
||||
|
||||
----
|
||||
su – sogo
|
||||
defaults write sogod SOGoUserSources '(
|
||||
{
|
||||
CNFieldName = displayName;
|
||||
IDFieldName = cn;
|
||||
UIDFieldName = sAMAccountName;
|
||||
baseDN = "cn=Users,dc=example,dc=com";
|
||||
bindDN = "cn=Administrator,cn=Users,dc=example,dc=com";
|
||||
bindFields = (
|
||||
sAMAccountName
|
||||
);
|
||||
bindPassword = "%1OpenChange";
|
||||
canAuthenticate = YES;
|
||||
displayName = "Shared Addresses";
|
||||
hostname = "127.0.0.1";
|
||||
id = samba;
|
||||
isAddressBook = YES;
|
||||
port = 389;
|
||||
}
|
||||
)'
|
||||
----
|
||||
|
||||
Please refer to the _SOGo Installation and Configuration Guide_ for more
|
||||
information regarding `SOGoUserSources`.
|
||||
|
||||
IMAP Server and Trust
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An IMAP server supporting the ACL, UIDPLUS and QRESYNC IMAP extensions
|
||||
is required, such as Cyrus IMAP version 2.4 or later, or Dovecot version
|
||||
2.1 or later. If your current IMAP server does not support these
|
||||
extensions, you can use Dovecot's proxying capabilities. The follow
|
||||
configuration example makes Dovecot proxy all IMAP request to an
|
||||
existing server:
|
||||
|
||||
----
|
||||
auth_mechanisms = plain login
|
||||
imapc_host = inverse.ca
|
||||
imapc_port = 993
|
||||
imapc_ssl = imaps
|
||||
imapc_ssl_verify = no
|
||||
mail_gid = imapproxy
|
||||
mail_home = /home/imapproxy/%u
|
||||
mail_location = imapc:~/imapc
|
||||
mail_uid = imapproxy
|
||||
passdb {
|
||||
args = host=inverse.ca ssl=imaps port=993 ssl_ca_dir=/etc/pki/tls/certs
|
||||
default_fields = userdb_imapc_user=%u userdb_imapc_password=%w
|
||||
driver = imap
|
||||
}
|
||||
protocols = imap
|
||||
ssl = no
|
||||
userdb {
|
||||
driver = prefetch
|
||||
}
|
||||
----
|
||||
|
||||
SOGo would then be configured to use Dovecot's proxy as the IMAP server.
|
||||
|
||||
Moreover, the authentication mode in use by Windows with Samba and
|
||||
Exchange servers prevent the backend from knowing the real password
|
||||
being used by the user. This implies that the IMAP server must accept
|
||||
any passwords from the host on which Samba is running.
|
||||
|
||||
To accomplish this with Cyrus IMAP Server, set `sasl_pwcheck_method`
|
||||
to `alwaystrue` in `/etc/imapd.conf`. You should restrain this to
|
||||
an `imapd` instance dedicated to SOGo.
|
||||
|
||||
For Dovecot, use an authentication source similar to:
|
||||
|
||||
----
|
||||
passdb {
|
||||
driver = static
|
||||
args = nopassword=y allow_nets=127.0.0.1/32
|
||||
}
|
||||
----
|
||||
|
||||
You should also make sure that you restrain this only to the SOGo
|
||||
processes.
|
||||
|
||||
For any other IMAP server, refer to the product's documentation. If such
|
||||
capability is not offered, you can alternatively define the cleartext
|
||||
password for each user. Please refer to the _Adding Users_ section from
|
||||
this document.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
This section will guide you through the installation of the native
|
||||
Microsoft Outlook compatibility layer SOGo offers.
|
||||
|
||||
Red Hat Enterprise Linux v5 and v6
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are using Red Hat Enterprise Linux (or CentOS) version 5 or
|
||||
version 6, packages for Samba 4, OpenChange and SOGo and the SOGo
|
||||
OpenChange backend are available from SOGo's web site. Please follow the
|
||||
instructions from
|
||||
http://www.sogo.nu/english/downloads/backend_nightly.html.
|
||||
|
||||
In order to satisfy certain dependencies, you should also add the EPEL
|
||||
source corresponding to your distribution and architecture. More
|
||||
information on this is available here:
|
||||
http://fedoraproject.org/wiki/EPEL – or more specifically,
|
||||
http://fedoraproject.org/wiki/EPEL/FAQ#How_can_I_install_the_packages_from_the_EPEL_software_repository.3F.
|
||||
|
||||
Once ready, install the OpenChange packages on top of an existing SOGo
|
||||
installation:
|
||||
|
||||
----
|
||||
yum clean all && yum makecache
|
||||
yum install samba4 \
|
||||
openchange \
|
||||
sogo-openchange-backend \
|
||||
openchange-ocsmanager \
|
||||
openchange-rpcproxy
|
||||
----
|
||||
|
||||
Once the packages are installed, refer to the _Configuration_ chapter
|
||||
from this guide.
|
||||
|
||||
Debian 6.0 (Squeeze) and Ubuntu 12.04 (Precise Pangolin)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Samba 4, OpenChange, SOGo and the SOGo OpenChange backend are now
|
||||
available from SOGo's web site. Please follow the instructions from
|
||||
http://www.sogo.nu/english/downloads/backend_nightly.html to setup your
|
||||
apt sources.
|
||||
|
||||
Debian Squeeze ships an older version of some libraries required by
|
||||
Samba 4. In order to workaround this, users of this distribution will
|
||||
have to use the _squeeze-backports_ repository. To do so, create
|
||||
`/etc/apt/sources.list.d/backports.list`:
|
||||
|
||||
deb http://backports.debian.org/debian-backports squeeze-backports main
|
||||
|
||||
Then install the dependencies on Debian Squeeze, do:
|
||||
|
||||
----
|
||||
apt-get update
|
||||
apt-get install -t squeeze-backports libwbclient-dev samba-common smbclient libsmbclient libsmbclient-dev
|
||||
----
|
||||
|
||||
Once ready, install the `samba4` package on top of an existing SOGo
|
||||
installation:
|
||||
|
||||
----
|
||||
apt-get update
|
||||
apt-get install samba4
|
||||
----
|
||||
|
||||
The current post installation script shipped with the Samba 4 package is
|
||||
far from perfect and might fail even on a fresh install. The following
|
||||
command is needed to let dpkg know that everything is fine about Samba 4
|
||||
if the post install script fails.
|
||||
|
||||
sed --in-place 'N; s/Package: samba4\nStatus: install ok half-configured/Package: samba4\nStatus: install ok installed/;' /var/lib/dpkg/status
|
||||
|
||||
Once completed, install the packages related to OpenChange and the SOGo
|
||||
provider:
|
||||
|
||||
----
|
||||
apt-get install openchangeserver \
|
||||
sogo-openchange \
|
||||
openchangeproxy \
|
||||
openchange-ocsmanager \
|
||||
openchange-rpcproxy
|
||||
----
|
||||
|
||||
Once the packages are installed, refer to the _Configuration_ chapter
|
||||
from this guide.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
In this section, you'll learn how to configure the native Microsoft
|
||||
Outlook compatibility layer that SOGo offers.
|
||||
|
||||
SOGo Configuration
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First thing to do is to configure SOGo to use your current services,
|
||||
which are your IMAP, SMTP and SQL database servers. The configuration
|
||||
instructions for this are available in the SOGo Installation and
|
||||
Configuration Guide available from http://www.sogo.nu/.
|
||||
|
||||
Please refer to that documentation before continuing with the
|
||||
instructions included in this guide.
|
||||
|
||||
Samba 4 Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Run the following commands as root:
|
||||
|
||||
----
|
||||
samba-tool domain provision --realm=example.com \
|
||||
--domain=OPENCHANGE \
|
||||
--adminpass='%1OpenChange' \
|
||||
--server-role='domain controller'
|
||||
|
||||
samba-tool user setexpiry administrator --noexpiry
|
||||
----
|
||||
|
||||
You might consider changing the realm and domain used, to suit your
|
||||
enviroment.
|
||||
|
||||
You might also have to
|
||||
remove `/etc/samba4/smb.conf` (or `/etc/samba/smb.conf` on Debian-based
|
||||
distributions) prior running this command.
|
||||
|
||||
Add the following parameters to the `[global]` section of the
|
||||
`/etc/samba4/smb.conf` (`/samba/smb.conf` if you use a Debian-based
|
||||
distribution) configuration file:
|
||||
|
||||
----
|
||||
### Configuration required by OpenChange server ###
|
||||
dcerpc endpoint servers = +epmapper, +mapiproxy
|
||||
dcerpc_mapiproxy:server = true
|
||||
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
|
||||
### Configuration required by OpenChange server ###
|
||||
----
|
||||
|
||||
Your Samba 4 configuration file should look like this:
|
||||
|
||||
----
|
||||
# Global parameters
|
||||
[global]
|
||||
server role = active directory domain controller
|
||||
workgroup = EXAMPLE
|
||||
realm = example.com
|
||||
netbios name = sogo
|
||||
passdb backend = samba4
|
||||
### Configuration required by OpenChange server ###
|
||||
dcerpc endpoint servers = +epmapper, +mapiproxy
|
||||
dcerpc_mapiproxy:server = true
|
||||
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
|
||||
### Configuration required by OpenChange server ###
|
||||
|
||||
[netlogon]
|
||||
path = /var/lib/samba/sysvol/example.com/scripts
|
||||
read only = No
|
||||
|
||||
[sysvol]
|
||||
path = /var/lib/samba/sysvol
|
||||
read only = No
|
||||
----
|
||||
|
||||
OpenChange Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Samba AD schema needs to be filled with additional object
|
||||
definitions by running the following commands:
|
||||
|
||||
----
|
||||
openchange_provision
|
||||
|
||||
NOTE: This operation can take several minutes
|
||||
[+] Step 1: Register Exchange OIDs
|
||||
[+] Step 2: Add Exchange attributes to Samba schema
|
||||
[+] Step 3: Add Exchange auxiliary classes to Samba schema
|
||||
[+] Step 4: Add Exchange objectCategory to Samba schema
|
||||
[+] Step 5: Add Exchange containers to Samba schema
|
||||
[+] Step 6: Add Exchange *sub* containers to Samba schema
|
||||
[+] Step 7: Add Exchange CfgProtocol subcontainers to Samba schema
|
||||
[+] Step 8: Add Exchange mailGateway subcontainers to Samba schema
|
||||
[+] Step 9: Add Exchange classes to Samba schema
|
||||
[+] Step 10: Add possSuperior attributes to Exchange classes
|
||||
[+] Step 11: Extend existing Samba classes and attributes
|
||||
[+] Step 12: Exchange Samba with Exchange configuration objects
|
||||
[SUCCESS] Done!
|
||||
----
|
||||
|
||||
You can safely ignore the "`ERROR: no subClassOf 'serviceAdministrationPoint' for 'rRASAdministrationConnectionPoint'`" message when running the `openchange_provision` command.
|
||||
|
||||
Provision the OpenChange database:
|
||||
|
||||
----
|
||||
openchange_provision --openchangedb
|
||||
|
||||
Setting up openchange db
|
||||
[+] Public Folders
|
||||
===================
|
||||
* Public Folder Root 0x0100000000000001
|
||||
* IPM_SUBTREE 0x0200000000000001
|
||||
* NON_IPM_SUBTREE 0x0300000000000001
|
||||
* EFORMS REGISTRY 0x0400000000000001
|
||||
* OFFLINE ADDRESS BOOK 0x0500000000000001
|
||||
* /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book 0x0600000000000001
|
||||
* SCHEDULE+ FREE BUSY 0x0700000000000001
|
||||
* EX:/o=First Organization/ou=Exchange Administrative Group (UBUNTU-OC) 0x0800000000000001
|
||||
* Events Root 0x0900000000000001
|
||||
----
|
||||
|
||||
On RHEL, make sure SELinux is disabled:
|
||||
|
||||
setenforce 0
|
||||
|
||||
Next, you can start Samba using the usual command :
|
||||
|
||||
/etc/init.d/samba4 start
|
||||
|
||||
You can also launch the OpenChange web services:
|
||||
|
||||
/etc/init.d/openchange-ocsmanager start
|
||||
|
||||
Apache Configuration for Web Services
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The OpenChange web services consist of two components:
|
||||
|
||||
1. *OCS Manager* which is used for autodiscovery and freebusy lookups on
|
||||
Outlook 2007 and 2010. This service runs in its own application server
|
||||
which listens on `127.0.0.1:5000` by default. Apache needs to be
|
||||
configured to forward certain requests to it to make it accessible from
|
||||
the outside.
|
||||
Note that this service *MUST* be accessible over*HTTPS*, otherwise Outlook
|
||||
won't use it.
|
||||
2. *RPC Proxy* which is used for RPC over HTTP ("Outlook Anywhere").
|
||||
This service runs as a WSGI application under apache (mod_wsgi).
|
||||
While HTTPS is not required to access this service, it is strongly
|
||||
recommended.
|
||||
|
||||
On RHEL-based distributions, the apache configuration required by these
|
||||
services can be found in `/etc/httpd/conf.d/ocsmanager.conf` and
|
||||
`/etc/httpd/conf.d/rpcproxy.conf`.
|
||||
|
||||
For Debian-based distributions, these files can be found
|
||||
in `/etc/apache2/conf.d/`.
|
||||
|
||||
The configuration requires three Apache modules: _mod_proxy_,
|
||||
_mod_proxy_http_ and _mod_wsgi_. These are usually already installed but
|
||||
might need to be activated on Debian-based installations:
|
||||
|
||||
a2enmod proxy proxy_http wsgi
|
||||
|
||||
On RHEL-based distributions, make sure the `LoadModule` directive is
|
||||
uncommented in `/etc/httpd/conf.d/wsgi.conf` (or
|
||||
`python26-mod_wsgi.conf` on RHELv5).
|
||||
|
||||
The _reqtimeout_ apache module is known to cause problems when using the
|
||||
default configuration shipped with Debian-based systems. On such
|
||||
distributions, apache will close (HTTP/1.1 500) any HTTP request for
|
||||
which the HTTP body hasn't arrived in 10 seconds.
|
||||
|
||||
While this is arguably good practice with regular HTTP, it will disrupt
|
||||
the RPC over HTTP protocol implemented by RPC Proxy: Outlook will
|
||||
continuously disconnect and reconnect leading to suboptimal performance.
|
||||
|
||||
To avoid this problem, use a much higher timeout or disable the module:
|
||||
|
||||
a2dismod reqtimeout
|
||||
|
||||
You should now restart the Apache service and make sure it will start on
|
||||
boot. On RHEL-based distributions, do:
|
||||
|
||||
chkconfig httpd on && /etc/init.d/httpd restart
|
||||
|
||||
On Debian-based distributions, do:
|
||||
|
||||
update-rc.d apache2 defaults && /etc/init.d/apache2 restart
|
||||
|
||||
Name Service Configuration for Web Services
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The autodiscovery service must be made accessible in order to advertise
|
||||
the web services provided by OpenChange. This can be done in two ways.
|
||||
|
||||
1. The first is to associate the FQDN `autodiscover.example.com.` with
|
||||
the machine that hosts Samba 4 / OpenChange, by adding a `CNAME` entry
|
||||
in your DNS configuration. Note that, instead or changing your DNS
|
||||
server configuration, you can simply add a similar entry to the _hosts_
|
||||
file of the Windows machine from where you'll run Outlook, which is
|
||||
handy for testing purposes.
|
||||
2. The second option is to add a `SRV` entry to your DNS configuration
|
||||
where the `_service` value would be `Autodiscover` and the `_protocol`
|
||||
would be `_tcp`.
|
||||
|
||||
For example:
|
||||
|
||||
_autodiscover._tcp.example.com. IN SRV 0 0 443 sogo.example.com.
|
||||
|
||||
Again, the autodiscovery service must be accessible over HTTPS.
|
||||
|
||||
Adding Users
|
||||
------------
|
||||
|
||||
Users that wish to connect natively to SOGo must be provisioned in
|
||||
Samba 4 and in OpenChange – even if they already exist in your current
|
||||
LDAP or Microsoft Active Directory server.
|
||||
|
||||
To add a user, execute the following commands:
|
||||
|
||||
----
|
||||
# add user to samba
|
||||
samba-tool domain passwordsettings set --complexity=off
|
||||
samba-tool domain passwordsettings set --min-pwd-length=1
|
||||
samba-tool user add <username>
|
||||
samba-tool user setexpiry <username> --noexpiry
|
||||
# create user in openchange+ +openchange_newuser --create <username>
|
||||
----
|
||||
|
||||
If you don't have a trust between your IMAP server and SOGo, you must at
|
||||
this point set the cleartext password of the newly created user in
|
||||
`/var/lib/samba4/private/mapistore/<username/password` (or
|
||||
`/var/lib/samba/private/mapistore/<username/password` on Debian-based
|
||||
distributions).
|
||||
|
||||
This per-user file contains the cleartext password of the user as a
|
||||
UTF-8 string, on a single line. This password will be used to
|
||||
authenticate SOGo/OpenChange storage provider to your IMAP server.
|
||||
|
||||
Microsoft Outlook Configuration
|
||||
-------------------------------
|
||||
|
||||
To connect Microsoft Outlook, you can either use the IP address of the
|
||||
server or its DNS name. If you prefer using the DNS name, add an entry
|
||||
like the following to the `c:\windows\system32\drivers\etc\hosts` file
|
||||
in order to associate the IP address with the right DNS names:
|
||||
|
||||
192.168.1.1 sogo.example.com autodiscover.example.com
|
||||
|
||||
Next, you must configure Microsoft Outlook.
|
||||
|
||||
* Open the Control Panel => Mail => Email Accounts.
|
||||
* Select _Add a new e-mail account_
|
||||
* Choose _Microsoft Exchange Server_
|
||||
* Fill the required information. Enter the DNS name or the IP address of
|
||||
your SOGo server in the _Microsoft Exchange Server_ field
|
||||
* Leave the _Use Cached Exchange Mode_ checkbox enabled
|
||||
* Enter your username in the _User Name_ field
|
||||
* Click on _More Settings_ and ignore the warning, if any, about
|
||||
Exchange being offline by clicking on Cancel
|
||||
* From the Security tab, enable Always prompt for user name and password
|
||||
* From the _Connection_ tab, enable _"Outlook Anywhere"_ if you plan to
|
||||
use Outlook outside of your LAN. Moreover, click on the _Exchange Proxy
|
||||
Settings..._ button to enable it for slow and fast networks. Specify
|
||||
also the host, which should be the same value you specified in the
|
||||
Microsoft Exchange Server field.
|
||||
* Finally, click on Check Name and confirm your username and password
|
||||
|
||||
Start Microsoft Outlook and enter your username and password. It will
|
||||
start to synchronize your mailbox. This could take a long time if you
|
||||
have many emails, events, tasks and contacts. Once this step is
|
||||
completed, check the autodiscovery service with Outlook 2007 or 2010 by
|
||||
simultaneously holding the CTRL key on your keyboard and right-clicking
|
||||
on the Outlook icon in the notification toolbar. A special entry named
|
||||
"Test E-mail AutoConfiguration..." will appear and will enable you to
|
||||
check the service.
|
||||
|
||||
Known Issues or Limitations
|
||||
---------------------------
|
||||
|
||||
* Make sure you periodically backup all your data regarding SOGo.
|
||||
* Make sure you have no firewalls activated between your Microsoft
|
||||
Outlook clients and the SOGo server with Native Outlook Compatibility
|
||||
module. If you do, use "Outlook Anywhere" to connect Outlook to
|
||||
SOGo/OpenChange.
|
||||
|
||||
Current Limitations
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The current version of the Native Microsoft Outlook compatibility layer
|
||||
has some limitations.
|
||||
|
||||
Those limitations will be overcome in the upcoming releases. If you are
|
||||
interested in having those limitations fixed more rapidly, please
|
||||
contact Inverse by sending an email to support@inverse.ca.
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
* If you can't see any email's content with Microsoft Outlook 2007,
|
||||
install the latest Service Pack available from Microsoft's website for
|
||||
this specific version. Microsoft Outlook 2007 (12.0.6423.100) SP2 MSO
|
||||
(12.0.6425.1000) is known to work.
|
||||
* When you create a new Microsoft Outlook profile, not all folders might
|
||||
be synchronized during the first start. Simply select the appropriate
|
||||
folder and click "Send and Receive". Synchronizing a folder may take
|
||||
some time. For example, a folder with 1000 email messages might take
|
||||
around 5 minutes based on the underlying hardware.
|
||||
* Errors when synchronizing the "Offline Address Book" are normal and
|
||||
can be ignored for now. This feature is currently not supported.
|
||||
* If you face strange issues from Microsoft Outlook, you might want to
|
||||
remove any data associated with the user from the SOGo server and
|
||||
recreate a Microsoft Outlook profile.
|
||||
To remove any data associated to a user, use
|
||||
the `openchange_user_cleanup` script distributed with SOGo. The script
|
||||
can be found in `/usr/share/doc/sogo/` (`/usr/share/sogo-VERSION/` on
|
||||
RHEL).
|
||||
To reset a user, run the script as root:
|
||||
`python openchange_user_cleanup username`. See the usage output for additional options.
|
||||
* The "Out of Office Assistant" will not currently work. This feature
|
||||
has not been implemented.
|
||||
* Creating folders below INBOX (when not normally permitted by the IMAP
|
||||
server), below the Personal Calendar or Personal Address Book will work
|
||||
in Outlook cached mode but the server-side operation will fail and these
|
||||
folders will never be created. Potentially data loss can occur if the
|
||||
Outlook profile is destroyed. If you wan to create additional top-level
|
||||
mail folders, calendars or address books, open Outlook's folder list,
|
||||
select the top level node (usually, "email@example.com") and choose "New
|
||||
Folder..." from the contextual menu. Choose the relevant item types.
|
||||
|
||||
Mail
|
||||
^^^^
|
||||
|
||||
* Sharing mail folders is not supported.
|
||||
* To avoid possibly lossy conversion from RTF to HTML, Outlook should be
|
||||
configured to send all mails as HTML (or plaintext) instead of _Outlook
|
||||
Rich Text Format_.
|
||||
|
||||
Calendar
|
||||
^^^^^^^^
|
||||
|
||||
* Labels will not work.
|
||||
* It might be impossible to view event details from a shared calendar.
|
||||
This issue is being worked on.
|
||||
|
||||
Tasks
|
||||
^^^^^
|
||||
|
||||
* Tasks with start/due dates created from Outlook might not appear
|
||||
correctly in SOGo due to a timezone issue.
|
||||
* Reminders are not yet supported.
|
||||
* Assigning tasks will not work.
|
||||
|
||||
Contacts
|
||||
^^^^^^^^
|
||||
|
||||
* Categories will not work.
|
||||
* Distribution lists will not work.
|
||||
* Under Microsoft Outlook 2010, the special folder "Suggested Contacts"
|
||||
will not work.
|
||||
* The "Offline Address Book" will not work. This feature is not yet
|
||||
supported.
|
||||
|
||||
Notes
|
||||
^^^^^
|
||||
|
||||
* Notes are not synchronized in any ways with SOGo. The current version
|
||||
of SOGo lacks support for notes.
|
||||
|
||||
If you notice anything else, please send contact Inverse by sending an
|
||||
email to support@inverse.ca.
|
||||
|
||||
include::includes/additional-info.asciidoc[]
|
||||
|
||||
include::includes/commercial-support.asciidoc[]
|
||||
|
Before Width: | Height: | Size: 401 KiB |
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# fop fix to build our documentation on CentOS 6
|
||||
#
|
||||
# Inverse inc. <info@inverse.ca>
|
||||
#
|
||||
--- /usr/bin/fop.orig 2012-01-17 21:25:50.000000000 -0500
|
||||
+++ /usr/bin/fop 2012-01-17 21:26:04.000000000 -0500
|
||||
@@ -26,7 +26,7 @@
|
||||
# Set parameters
|
||||
set_jvm
|
||||
set_classpath commons-io batik-all avalon-framework xmlgraphics-commons \
|
||||
- commons-logging fop
|
||||
+ commons-logging fop xalan-j2
|
||||
set_flags $BASE_FLAGS
|
||||
set_options $BASE_OPTIONS
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# xmlgraphics-fop fix to build our documentation on CentOS 5
|
||||
# taken from https://build.opensuse.org/request/show/68994
|
||||
#
|
||||
# Inverse inc. <info@inverse.ca>
|
||||
#
|
||||
--- /usr/bin/xmlgraphics-fop.orig 2012-01-17 18:42:08.000000000 -0500
|
||||
+++ /usr/bin/xmlgraphics-fop 2012-01-17 18:42:18.000000000 -0500
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
# Rest of the configuration
|
||||
MAIN_CLASS=org.apache.fop.cli.Main
|
||||
-BASE_JARS="xmlgraphics-fop xmlgraphics-batik/util xml-commons-jaxp-1.3-apis excalibur/avalon-framework-api xerces-j2 xalan-j2 xalan-j2-serializer"
|
||||
+BASE_JARS="xmlgraphics-fop batik-all xml-commons-jaxp-1.3-apis excalibur/avalon-framework-impl excalibur/avalon-framework-api xerces-j2 xalan-j2 xalan-j2-serializer"
|
||||
|
||||
# Set parameters
|
||||
set_jvm
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<!-- ********************************************************************
|
||||
|
||||
Header / Footer customizations
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2011-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
******************************************************************** -->
|
||||
|
||||
<!--
|
||||
Here we are re-defining docbook-xsl/fo/pagesetup.xsl to fit our needs.
|
||||
- top: chapter number on the left
|
||||
- bottom: copyright, chapter name, page
|
||||
-->
|
||||
|
||||
<xsl:param name="header.rule" select="0"/>
|
||||
|
||||
<xsl:template name="header.content">
|
||||
<xsl:param name="pageclass" select="''"/>
|
||||
<xsl:param name="sequence" select="''"/>
|
||||
<xsl:param name="position" select="''"/>
|
||||
<xsl:param name="gentext-key" select="''"/>
|
||||
|
||||
<fo:block>
|
||||
<!-- sequence can be odd, even, first, blank -->
|
||||
<!-- position can be left, center, right -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$sequence = 'blank'">
|
||||
<!-- nothing -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="($sequence='first' or $sequence='odd' or $sequence='even') and $position='left'">
|
||||
<xsl:if test="$pageclass != 'titlepage' and $pageclass != 'lot'">
|
||||
<xsl:call-template name="gentext">
|
||||
<xsl:with-param name="key" select="'chapter'"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="gentext.space"/>
|
||||
<xsl:number count="chapter" from="book" level="any"/>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
|
||||
<!-- draft -->
|
||||
<xsl:when test="$position='right'">
|
||||
<xsl:call-template name="draft.text"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:param name="footer.rule" select="0"/>
|
||||
<xsl:template name="footer.content">
|
||||
<xsl:param name="pageclass" select="''"/>
|
||||
<xsl:param name="sequence" select="''"/>
|
||||
<xsl:param name="position" select="''"/>
|
||||
<xsl:param name="gentext-key" select="''"/>
|
||||
|
||||
<fo:block>
|
||||
<!-- pageclass can be front, body, back -->
|
||||
<!-- sequence can be odd, even, first, blank -->
|
||||
<!-- position can be left, center, right -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$pageclass = 'titlepage'">
|
||||
<!-- nop; no footer on title pages -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided = 0 and $position='left'">
|
||||
<xsl:apply-templates select="//copyright[1]" mode="titlepage.mode"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="($sequence='first' or $sequence='odd' or $sequence='even') and $position='center'">
|
||||
<xsl:if test="$pageclass != 'titlepage' and $pageclass != 'lot'">
|
||||
<xsl:apply-templates select="." mode="titleabbrev.markup"/>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided = 0 and $position='right'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$sequence='blank'">
|
||||
<!-- nop -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
|
||||
@@ -0,0 +1,193 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<!-- ********************************************************************
|
||||
|
||||
SOGo Documentation Docbook FO Parameters
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2011-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
******************************************************************** -->
|
||||
|
||||
<!--
|
||||
Global Tasks
|
||||
|
||||
TODO prettier revhistory
|
||||
TODO prettier Table of Contents
|
||||
TODO generate PDF table of contents (like OSX's Preview shows on the right hand side)
|
||||
TODO title 2
|
||||
- align with text?
|
||||
- more above whitespace
|
||||
TODO change the bullet for a prettier one
|
||||
TODO title 3 and 4
|
||||
- align with text?
|
||||
- should be easier to differentiate (check network guide)
|
||||
TODO icon on line wrap in monospace boxes
|
||||
TODO caution, notes, warnings, etc.
|
||||
- box around it
|
||||
- sexy icon
|
||||
TODO -> is converted into an arrow but it's not pretty (is it font or docbook-thingy?)
|
||||
|
||||
-->
|
||||
|
||||
<!--
|
||||
Load default values
|
||||
|
||||
Real upstream schema is at:
|
||||
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
|
||||
|
||||
but we decided to load all sensible local xsd since it only produce a warning on missing imports.
|
||||
-->
|
||||
<!-- CentOS / RHEL -->
|
||||
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl"/>
|
||||
<!-- Debian / Ubuntu -->
|
||||
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl"/>
|
||||
<!-- OSX through mac ports -->
|
||||
<xsl:import href="/opt/local/share/xsl/docbook-xsl/fo/docbook.xsl"/>
|
||||
|
||||
<!-- title page extra styling -->
|
||||
<xsl:import href="titlepage-fo.xsl"/>
|
||||
|
||||
<!-- header / footer extra styling -->
|
||||
<xsl:import href="headerfooter-fo.xsl"/>
|
||||
|
||||
<!-- attaching an image to the verso legalnotice component -->
|
||||
<xsl:template match="legalnotice" mode="book.titlepage.verso.mode">
|
||||
<xsl:apply-templates mode="titlepage.mode"/>
|
||||
<fo:block text-align="right">
|
||||
<fo:external-graphic src="url('images/inverse-logo.jpg')" width="3in" content-width="scale-to-fit"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- stylesheet options -->
|
||||
<xsl:param name="title.font.family">Lato-Medium</xsl:param>
|
||||
<xsl:param name="chapter.autolabel" select="0"/>
|
||||
<xsl:attribute-set name="component.title.properties">
|
||||
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">solid 2px</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level1.properties">
|
||||
<xsl:attribute name="border-bottom">solid 1px</xsl:attribute>
|
||||
<xsl:attribute name="margin-top">1em</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level2.properties">
|
||||
<xsl:attribute name="margin-top">1em</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level3.properties">
|
||||
<xsl:attribute name="margin-top">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level4.properties">
|
||||
<xsl:attribute name="margin-top">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- paragraph spacing -->
|
||||
<xsl:attribute-set name="normal.para.spacing">
|
||||
<xsl:attribute name="space-before.optimum">1.5em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">1.5em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">2.2em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- default fonts -->
|
||||
<xsl:param name="body.font.family">Lato-Light</xsl:param>
|
||||
<xsl:param name="body.font.master">10</xsl:param>
|
||||
<xsl:param name="monospace.font.family">Incosolata</xsl:param>
|
||||
|
||||
<!-- revision table layout -->
|
||||
<xsl:attribute-set name="revhistory.title.properties">
|
||||
<xsl:attribute name="font-size">12pt</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="text-align">center</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="revhistory.table.properties">
|
||||
<xsl:attribute name="break-before">page</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="revhistory.table.cell.properties">
|
||||
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Table Of Contents (TOC) options -->
|
||||
<!-- We only want 2 level of ToC depth -->
|
||||
<xsl:param name="toc.section.depth" select="2"/>
|
||||
|
||||
<!-- titles left margin -->
|
||||
<xsl:attribute-set name="section.title.properties">
|
||||
<xsl:attribute name="start-indent"><xsl:value-of select="$body.start.indent"/></xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="list.item.spacing">
|
||||
<xsl:attribute name="space-before.optimum">0em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.2em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- lists type -->
|
||||
<xsl:template name="itemizedlist.label.markup">
|
||||
<xsl:param name="itemsymbol" select="'square'"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemsymbol='square'"><fo:inline font-family="Lato">∏</fo:inline></xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
<xsl:template name="next.itemsymbol">
|
||||
<xsl:param name="itemsymbol" select="'default'"/>
|
||||
<xsl:choose>
|
||||
<xsl:otherwise>square</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- admonition -->
|
||||
<xsl:param name="admon.graphics" select="1"></xsl:param>
|
||||
<xsl:param name="admon.graphics.path">images/</xsl:param>
|
||||
<xsl:param name="admon.graphics.extension">.png</xsl:param>
|
||||
<xsl:attribute-set name="graphical.admonition.properties">
|
||||
<xsl:attribute name="border-top">1px solid</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
|
||||
<!-- grey boxes around code (screen, programlisting) -->
|
||||
<xsl:param name="shade.verbatim" select="1"/>
|
||||
<xsl:attribute-set name="shade.verbatim.style">
|
||||
<xsl:attribute name="background-color">#E0E0E0</xsl:attribute>
|
||||
<xsl:attribute name="border">thin #9F9F9F solid</xsl:attribute>
|
||||
<xsl:attribute name="margin">0pt</xsl:attribute>
|
||||
<xsl:attribute name="padding">0.5em</xsl:attribute>
|
||||
<!-- prevent page breaks in screen and programlisting tags -->
|
||||
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- breaking long lines in code (screen, programlisting) -->
|
||||
<xsl:attribute-set name="monospace.verbatim.properties">
|
||||
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- don't show raw links in [ .. ] after a link -->
|
||||
<xsl:param name="ulink.show" select="0"/>
|
||||
|
||||
<!-- blue underlined hyperlink -->
|
||||
<xsl:attribute-set name="xref.properties">
|
||||
<xsl:attribute name="color">blue</xsl:attribute>
|
||||
<xsl:attribute name="text-decoration">underline</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- copyright in range instead of seperated years -->
|
||||
<xsl:param name="make.year.ranges" select="1" />
|
||||
|
||||
<!-- variablelist behavior (asciidoc's term:: lists) -->
|
||||
<!-- <xsl:param name="variablelist.term.break.after" select="1" /> -->
|
||||
|
||||
</xsl:stylesheet>
|
||||
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
|
||||
@@ -0,0 +1,175 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<!-- ********************************************************************
|
||||
|
||||
SOGo Documentation Docbook FO Parameters
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2011-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
******************************************************************** -->
|
||||
|
||||
<!--
|
||||
Global Tasks
|
||||
|
||||
TODO prettier revhistory
|
||||
TODO prettier Table of Contents
|
||||
TODO generate PDF table of contents (like OSX's Preview shows on the right hand side)
|
||||
TODO title 2
|
||||
- align with text?
|
||||
- more above whitespace
|
||||
TODO change the bullet for a prettier one
|
||||
TODO title 3 and 4
|
||||
- align with text?
|
||||
- should be easier to differentiate (check network guide)
|
||||
TODO icon on line wrap in monospace boxes
|
||||
TODO caution, notes, warnings, etc.
|
||||
- box around it
|
||||
- sexy icon
|
||||
TODO -> is converted into an arrow but it's not pretty (is it font or docbook-thingy?)
|
||||
|
||||
-->
|
||||
|
||||
<!--
|
||||
Load default values
|
||||
|
||||
Real upstream schema is at:
|
||||
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
|
||||
|
||||
but we decided to load all sensible local xsd since it only produce a warning on missing imports.
|
||||
-->
|
||||
<!-- CentOS / RHEL -->
|
||||
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl"/>
|
||||
<!-- Debian / Ubuntu -->
|
||||
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl"/>
|
||||
<!-- OSX through mac ports -->
|
||||
<xsl:import href="/opt/local/share/xsl/docbook-xsl/fo/docbook.xsl"/>
|
||||
|
||||
<!-- title page extra styling -->
|
||||
<xsl:import href="titlepage-fo.xsl"/>
|
||||
|
||||
<!-- header / footer extra styling -->
|
||||
<xsl:import href="headerfooter-fo.xsl"/>
|
||||
|
||||
<!-- attaching an image to the verso legalnotice component -->
|
||||
<xsl:template match="legalnotice" mode="book.titlepage.verso.mode">
|
||||
<xsl:apply-templates mode="titlepage.mode"/>
|
||||
<fo:block text-align="right">
|
||||
<fo:external-graphic src="url('images/inverse-logo.jpg')" width="3in" content-width="scale-to-fit"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- stylesheet options -->
|
||||
<xsl:param name="title.font.family">Lato-Medium</xsl:param>
|
||||
<xsl:param name="chapter.autolabel" select="0"/>
|
||||
<xsl:attribute-set name="component.title.properties">
|
||||
<xsl:attribute name="padding-bottom">2.5em</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">solid 2px</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level1.properties">
|
||||
<xsl:attribute name="border-bottom">solid 1px</xsl:attribute>
|
||||
<xsl:attribute name="margin-top">2em</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- titles spacing -->
|
||||
<xsl:attribute-set name="section.title.level2.properties">
|
||||
<xsl:attribute name="margin-top">1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- default fonts -->
|
||||
<xsl:param name="body.font.family">Lato-Light</xsl:param>
|
||||
<xsl:param name="body.font.master">10</xsl:param>
|
||||
<xsl:param name="monospace.font.family">Incosolata</xsl:param>
|
||||
|
||||
<!-- revision table layout -->
|
||||
<xsl:attribute-set name="revhistory.title.properties">
|
||||
<xsl:attribute name="font-size">12pt</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="text-align">center</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="revhistory.table.properties">
|
||||
<xsl:attribute name="break-before">page</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="revhistory.table.cell.properties">
|
||||
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Table Of Contents (TOC) options -->
|
||||
<!-- We only want 2 level of ToC depth -->
|
||||
<xsl:param name="toc.section.depth" select="1"/>
|
||||
|
||||
<!-- titles left margin -->
|
||||
<xsl:attribute-set name="section.title.properties">
|
||||
<xsl:attribute name="start-indent"><xsl:value-of select="$body.start.indent"/></xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- lists type -->
|
||||
<xsl:template name="itemizedlist.label.markup">
|
||||
<xsl:param name="itemsymbol" select="'square'"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemsymbol='square'"><fo:inline font-family="Lato-Light">▪</fo:inline></xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
<xsl:template name="next.itemsymbol">
|
||||
<xsl:param name="itemsymbol" select="'default'"/>
|
||||
<xsl:choose>
|
||||
<xsl:otherwise>square</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- admonition -->
|
||||
<xsl:param name="admon.graphics" select="1"></xsl:param>
|
||||
<xsl:param name="admon.graphics.path">images/</xsl:param>
|
||||
<xsl:param name="admon.graphics.extension">.png</xsl:param>
|
||||
<xsl:attribute-set name="graphical.admonition.properties">
|
||||
<xsl:attribute name="border-top">1px solid</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
|
||||
<!-- grey boxes around code (screen, programlisting) -->
|
||||
<xsl:param name="shade.verbatim" select="1"/>
|
||||
<xsl:attribute-set name="shade.verbatim.style">
|
||||
<xsl:attribute name="background-color">#E0E0E0</xsl:attribute>
|
||||
<xsl:attribute name="border">thin #9F9F9F solid</xsl:attribute>
|
||||
<xsl:attribute name="margin">0pt</xsl:attribute>
|
||||
<xsl:attribute name="padding">0.5em</xsl:attribute>
|
||||
<!-- prevent page breaks in screen and programlisting tags -->
|
||||
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- breaking long lines in code (screen, programlisting) -->
|
||||
<xsl:attribute-set name="monospace.verbatim.properties">
|
||||
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- don't show raw links in [ .. ] after a link -->
|
||||
<xsl:param name="ulink.show" select="0"/>
|
||||
|
||||
<!-- blue underlined hyperlink -->
|
||||
<xsl:attribute-set name="xref.properties">
|
||||
<xsl:attribute name="color">blue</xsl:attribute>
|
||||
<xsl:attribute name="text-decoration">underline</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- copyright in range instead of seperated years -->
|
||||
<xsl:param name="make.year.ranges" select="1" />
|
||||
|
||||
<!-- variablelist behavior (asciidoc's term:: lists) -->
|
||||
<!-- <xsl:param name="variablelist.term.break.after" select="1" /> -->
|
||||
|
||||
</xsl:stylesheet>
|
||||
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
|
||||
@@ -0,0 +1,96 @@
|
||||
<!DOCTYPE t:templates [
|
||||
<!ENTITY hsize0 "10pt">
|
||||
<!ENTITY hsize1 "12pt">
|
||||
<!ENTITY hsize2 "14.4pt">
|
||||
<!ENTITY hsize3 "17.28pt">
|
||||
<!ENTITY hsize4 "20.736pt">
|
||||
<!ENTITY hsize5 "24.8832pt">
|
||||
<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 -->
|
||||
<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 -->
|
||||
<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 -->
|
||||
<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 -->
|
||||
<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 -->
|
||||
<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 -->
|
||||
]>
|
||||
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
|
||||
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<!-- ********************************************************************
|
||||
|
||||
SOGo title page
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2011-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
******************************************************************** -->
|
||||
|
||||
<!--
|
||||
If you make changes you need to rebuild XSL:
|
||||
|
||||
xsltproc -o docs/docbook/xsl/titlepage-fo.xsl \
|
||||
/usr/share/xml/docbook/stylesheet/docbook-xsl/template/titlepage.xsl \
|
||||
docs/docbook/xsl/titlepage-fo.xml
|
||||
|
||||
On some platforms the titlepage.xsl is located elsewhere:
|
||||
* OSX: /opt/local/share/xsl/docbook-xsl/template/titlepage.xsl
|
||||
|
||||
This is a customized version of docbook-xsl/fo/titlepage.templates.xml.
|
||||
I removed every section except the book one. Feel free to add more if more
|
||||
customization are required.
|
||||
-->
|
||||
|
||||
<t:titlepage t:element="book" t:wrapper="fo:block">
|
||||
<t:titlepage-content t:side="recto">
|
||||
<mediaobject/>
|
||||
<title
|
||||
t:named-template="division.title"
|
||||
param:node="ancestor-or-self::book[1]"
|
||||
text-align="right"
|
||||
font-size="&hsize5;"
|
||||
space-before="&hsize5space;"
|
||||
font-weight="bold"
|
||||
font-family="{$title.fontset}"
|
||||
margin-top="8em"/>
|
||||
<subtitle
|
||||
text-align="right"
|
||||
font-size="&hsize4;"
|
||||
space-before="&hsize4space;"
|
||||
font-family="{$title.fontset}"
|
||||
border-bottom="solid"/>
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-content t:side="verso">
|
||||
<title
|
||||
font-size="&hsize2;"
|
||||
font-weight="bold"
|
||||
font-family="{$title.fontset}"/>
|
||||
<corpauthor/>
|
||||
<authorgroup t:named-template="verso.authorgroup"/>
|
||||
<author/>
|
||||
<othercredit/>
|
||||
<releaseinfo space-before="0.5em"/>
|
||||
<pubdate space-before="1em"/>
|
||||
<copyright/>
|
||||
<abstract/>
|
||||
<legalnotice font-size="8pt"/>
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-separator>
|
||||
<fo:block break-after="page"/>
|
||||
</t:titlepage-separator>
|
||||
|
||||
<t:titlepage-before t:side="recto">
|
||||
</t:titlepage-before>
|
||||
|
||||
<t:titlepage-before t:side="verso">
|
||||
<fo:block break-after="page"/>
|
||||
</t:titlepage-before>
|
||||
</t:titlepage>
|
||||
|
||||
</t:templates>
|
||||
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="exsl">
|
||||
|
||||
<!-- This stylesheet was created by template/titlepage.xsl-->
|
||||
|
||||
<xsl:template name="book.titlepage.recto">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/mediaobject"/>
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/mediaobject"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="bookinfo/title">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/title"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="info/title">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/title"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="title">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="title"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="bookinfo/subtitle">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/subtitle"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="info/subtitle">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/subtitle"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="subtitle">
|
||||
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="subtitle"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="book.titlepage.verso">
|
||||
<xsl:choose>
|
||||
<xsl:when test="bookinfo/title">
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/title"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="info/title">
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/title"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="title">
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="title"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/corpauthor"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/corpauthor"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/authorgroup"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/authorgroup"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/author"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/author"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/othercredit"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/othercredit"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/releaseinfo"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/releaseinfo"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/pubdate"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/pubdate"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/copyright"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/copyright"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/abstract"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/abstract"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/legalnotice"/>
|
||||
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/legalnotice"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="book.titlepage.separator"><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" break-after="page"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="book.titlepage.before.recto">
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="book.titlepage.before.verso"><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" break-after="page"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="book.titlepage">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
<xsl:variable name="recto.content">
|
||||
<xsl:call-template name="book.titlepage.before.recto"/>
|
||||
<xsl:call-template name="book.titlepage.recto"/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="recto.elements.count">
|
||||
<xsl:choose>
|
||||
<xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
|
||||
<xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
|
||||
<!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
|
||||
<xsl:otherwise>1</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:if test="(normalize-space($recto.content) != '') or ($recto.elements.count > 0)">
|
||||
<fo:block><xsl:copy-of select="$recto.content"/></fo:block>
|
||||
</xsl:if>
|
||||
<xsl:variable name="verso.content">
|
||||
<xsl:call-template name="book.titlepage.before.verso"/>
|
||||
<xsl:call-template name="book.titlepage.verso"/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="verso.elements.count">
|
||||
<xsl:choose>
|
||||
<xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
|
||||
<xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
|
||||
<!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
|
||||
<xsl:otherwise>1</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:if test="(normalize-space($verso.content) != '') or ($verso.elements.count > 0)">
|
||||
<fo:block><xsl:copy-of select="$verso.content"/></fo:block>
|
||||
</xsl:if>
|
||||
<xsl:call-template name="book.titlepage.separator"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*" mode="book.titlepage.recto.mode">
|
||||
<!-- if an element isn't found in this mode, -->
|
||||
<!-- try the generic titlepage.mode -->
|
||||
<xsl:apply-templates select="." mode="titlepage.mode"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*" mode="book.titlepage.verso.mode">
|
||||
<!-- if an element isn't found in this mode, -->
|
||||
<!-- try the generic titlepage.mode -->
|
||||
<xsl:apply-templates select="." mode="titlepage.mode"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="mediaobject" mode="book.titlepage.recto.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.recto.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="title" mode="book.titlepage.recto.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style" text-align="right" font-size="24.8832pt" space-before="18.6624pt" font-weight="bold" font-family="{$title.fontset}" margin-top="8em">
|
||||
<xsl:call-template name="division.title">
|
||||
<xsl:with-param name="node" select="ancestor-or-self::book[1]"/>
|
||||
</xsl:call-template>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="subtitle" mode="book.titlepage.recto.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style" text-align="right" font-size="20.736pt" space-before="15.552pt" font-family="{$title.fontset}" border-bottom="solid">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.recto.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="title" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" font-size="14.4pt" font-weight="bold" font-family="{$title.fontset}">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="corpauthor" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="authorgroup" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:call-template name="verso.authorgroup">
|
||||
</xsl:call-template>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="author" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="othercredit" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="releaseinfo" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" space-before="0.5em">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="pubdate" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" space-before="1em">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="copyright" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="abstract" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="legalnotice" mode="book.titlepage.verso.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" font-size="8pt">
|
||||
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<!-- TODO have the build system take care of this -->
|
||||
<releaseinfo>Version 2.2.9 - September 2014</releaseinfo>
|
||||
<subtitle>for version 2.2.9</subtitle>
|
||||
<date>2014-09-26</date>
|
||||
|
||||
<legalnotice>
|
||||
<para>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".</para>
|
||||
|
||||
<!-- font licenses -->
|
||||
<para>The fonts used in this guide are licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: <ulink url="http://scripts.sil.org/OFL">http://scripts.sil.org/OFL</ulink></para>
|
||||
<para>Copyright © Łukasz Dziedzic, <ulink url="http://www.latofonts.com/">http://www.latofonts.com</ulink>, with Reserved Font Name: "Lato".</para>
|
||||
<para>Copyright © Raph Levien, <ulink url="http://levien.com/">http://levien.com/</ulink>, with Reserved Font Name: "Inconsolata".</para>
|
||||
</legalnotice>
|
||||
<mediaobject>
|
||||
<objectinfo>
|
||||
<corpname>Inverse inc.</corpname>
|
||||
</objectinfo>
|
||||
<textobject>
|
||||
<phrase>SOGo logo</phrase>
|
||||
</textobject>
|
||||
<imageobject>
|
||||
<imagedata align="left" width="4in" format="PNG" fileref="images/sogo-logo.png" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
@@ -0,0 +1,32 @@
|
||||
<fop version="1.0">
|
||||
<renderers>
|
||||
<renderer mime="application/pdf">
|
||||
<fonts>
|
||||
<font metrics-url="fonts/inconsolata.xml" kerning="yes" embed-url="fonts/inconsolata.ttf">
|
||||
<font-triplet name="Incosolata" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-Regular.xml" kerning="yes" embed-url="fonts/lato/Lato-Regular.ttf">
|
||||
<font-triplet name="Lato" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-Italic.xml" kerning="yes" embed-url="fonts/lato/Lato-Italic.ttf">
|
||||
<font-triplet name="Lato" style="italic" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-Light.xml" kerning="yes" embed-url="fonts/lato/Lato-Light.ttf">
|
||||
<font-triplet name="Lato-Light" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-LightItalic.xml" kerning="yes" embed-url="fonts/lato/Lato-LightItalic.ttf">
|
||||
<font-triplet name="Lato-Light" style="italic" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-Medium.xml" kerning="yes" embed-url="fonts/lato/Lato-Medium.ttf">
|
||||
<font-triplet name="Lato-Medium" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-MediumItalic.xml" kerning="yes" embed-url="fonts/lato/Lato-MediumItalic.ttf">
|
||||
<font-triplet name="Lato-Medium" style="italic" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-url="fonts/lato/Lato-Semibold.xml" kerning="yes" embed-url="fonts/lato/Lato-Semibold.ttf">
|
||||
<font-triplet name="Lato-Semibold" style="normal" weight="normal"/>
|
||||
</font>
|
||||
</fonts>
|
||||
</renderer>
|
||||
</renderers>
|
||||
</fop>
|
||||
@@ -0,0 +1,41 @@
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
After Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,27 @@
|
||||
////
|
||||
|
||||
Additional information section
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2008-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
////
|
||||
|
||||
Additional Information
|
||||
----------------------
|
||||
|
||||
For more information, please consult the online FAQs (Frequently Asked
|
||||
Questions) :
|
||||
|
||||
http://www.sogo.nu/english/support/faq.html
|
||||
|
||||
You can also read the mailing archives or post your questions to it. For
|
||||
details, see :
|
||||
|
||||
https://lists.inverse.ca/sogo
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
@@ -0,0 +1,26 @@
|
||||
////
|
||||
|
||||
Commercial support section
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2008-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
////
|
||||
|
||||
Commercial Support and Contact Information
|
||||
------------------------------------------
|
||||
|
||||
For any questions or comments, do not hesitate to contact us by writing
|
||||
an email to :
|
||||
|
||||
mailto:support@inverse.ca[support@inverse.ca]
|
||||
|
||||
Inverse (http://inverse.ca/[http://inverse.ca]) offers professional
|
||||
services around SOGo to help organizations deploy the solution and
|
||||
migrate from their legacy systems.
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
@@ -0,0 +1,18 @@
|
||||
////
|
||||
|
||||
Global Attributes for our documentation
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2008-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
////
|
||||
|
||||
// TODO have the build system take care of this
|
||||
|
||||
:release_version: 2.2.9
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
@@ -0,0 +1,19 @@
|
||||
////
|
||||
|
||||
License section
|
||||
|
||||
This file is part of the SOGo project.
|
||||
Authors:
|
||||
- Inverse inc. <info@inverse.ca>
|
||||
|
||||
Copyright (C) 2008-2014 Inverse inc.
|
||||
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
|
||||
|
||||
////
|
||||
|
||||
GNU Free Documentation License
|
||||
------------------------------
|
||||
|
||||
Please refer to http://www.gnu.org/licenses/fdl-1.2.txt for the full license.
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
|
Before Width: | Height: | Size: 311 KiB |
|
Before Width: | Height: | Size: 55 KiB |
@@ -1,3 +1,28 @@
|
||||
2.2.9 (2014-09-26)
|
||||
------------------
|
||||
|
||||
New features
|
||||
- support for recurrent tasks (#2160)
|
||||
- support for alarms on recurrent events / tasks
|
||||
|
||||
Enchancements
|
||||
- alarms can now be snoozed for 1 day
|
||||
- better iOS/Mac OS X Calendar compability regarding alarms (#1920)
|
||||
- force default classification over CalDAV if none is set (#2326)
|
||||
- now compliant when handling completed tasks (#589)
|
||||
- better iOS invitations handling regarding part state (#2852)
|
||||
- fixed Mac OS X Calendar delegation issue (#2837)
|
||||
- converted ODT documentation to AsciiDoc format
|
||||
- updated Czech, Dutch, Finnish, French, German, Hungarian, Norwegian (Bokmal), Polish, Russian, and
|
||||
Spanish (Spain) translations
|
||||
|
||||
Bug fixes
|
||||
- fixed sending mails to multiple recipients over AS
|
||||
- fixed freebusy support in iCal 7 and free/busy state changes (#2878, #2879)
|
||||
- we now get rid of all potential control characters before sending the DAV response
|
||||
- sync-token can now be returned during PROPFIND (#2493)
|
||||
- fixed calendar deletion on iOS/Mac OS Calendar (#2838)
|
||||
|
||||
2.2.8 (2014-09-10)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy -lWEExte
|
||||
|
||||
$(MAPISTORESOGO)_INSTALL_DIR = $(DESTDIR)/$(SAMBA_LIB_DIR)/mapistore_backends
|
||||
$(MAPISTORESOGO)_LIB_DIRS += \
|
||||
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
|
||||
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \
|
||||
$(LIBMAPI_LIBS) \
|
||||
$(LIBMAPISTORE_LIBS)
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* GCSAlarmsFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2010-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -944,7 +944,7 @@ andAttribute: (EOAttribute *)_attribute
|
||||
|| *_baseVersion == [storedVersion unsignedIntValue])
|
||||
{
|
||||
/* extract quick info */
|
||||
quickRow = [theComponent performSelector: @selector(quickRecordForContainer:) withObject: theContainer];
|
||||
quickRow = [theComponent performSelector: @selector(quickRecordFromContent:container:) withObject: _content withObject: theContainer];
|
||||
if (quickRow)
|
||||
{
|
||||
[quickRow setObject:_name forKey:@"c_name"];
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
/* CardElement.h - this file is part of SOPE
|
||||
*
|
||||
* Copyright (C) 2006-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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,
|
||||
* 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.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* CardElement.m - this file is part of SOPE
|
||||
*
|
||||
* Copyright (C) 2006-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* iCalDateTime.m - this file is part of SOPE
|
||||
*
|
||||
* Copyright (C) 2006-2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
@@ -92,8 +90,8 @@
|
||||
calendar
|
||||
= (iCalCalendar *) [self searchParentOfClass: [iCalCalendar class]];
|
||||
timeZone = [calendar timeZoneWithId: tzId];
|
||||
if (!timeZone)
|
||||
[self logWithFormat: @"timezone '%@' not found in calendar", tzId];
|
||||
//if (!timeZone)
|
||||
//[self logWithFormat: @"timezone '%@' not found in calendar", tzId];
|
||||
}
|
||||
|
||||
return timeZone;
|
||||
|
||||
@@ -66,8 +66,6 @@
|
||||
- (BOOL) isWithinCalendarDateRange: (NGCalendarDateRange *) _range;
|
||||
- (NSArray *) recurrenceRangesWithinCalendarDateRange: (NGCalendarDateRange *)_r;
|
||||
|
||||
- (NSCalendarDate *) lastPossibleRecurrenceStartDate;
|
||||
|
||||
/* calculating changes */
|
||||
|
||||
- (iCalEventChanges *) getChangesRelativeToEvent: (iCalEvent *) _event;
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
|
||||
- (NSCalendarDate *) firstRecurrenceStartDateWithEndDate: (NSCalendarDate *) endDate;
|
||||
|
||||
- (NSCalendarDate *) lastPossibleRecurrenceStartDate;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __NGCards_iCalRepeatableEntityObject_H_ */
|
||||
|
||||
@@ -417,4 +417,11 @@ lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange: (NGCalendarD
|
||||
return firstOccurrenceStartDate;
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastPossibleRecurrenceStartDate
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/* iCalTimeZone.m - this file is part of SOPE
|
||||
*
|
||||
* Copyright (C) 2006-2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
* Francis Lachapelle <flachapelle@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* iCalTimeZonePeriod.m - this file is part of SOPE
|
||||
*
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#import "iCalDateTime.h"
|
||||
#import "iCalToDo.h"
|
||||
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
|
||||
@implementation iCalToDo
|
||||
|
||||
- (Class) classForTag: (NSString *) classTag
|
||||
@@ -119,4 +121,17 @@
|
||||
// return ms;
|
||||
// }
|
||||
|
||||
- (NSCalendarDate *) lastPossibleRecurrenceStartDate
|
||||
{
|
||||
NGCalendarDateRange *fir;
|
||||
|
||||
if (![self isRecurrent])
|
||||
return nil;
|
||||
|
||||
fir = [NGCalendarDateRange calendarDateRangeWithStartDate: [self startDate]
|
||||
endDate: [self due]];
|
||||
|
||||
return [self lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange: fir];
|
||||
}
|
||||
|
||||
@end /* iCalToDo */
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
<?php
|
||||
/* updates.php - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2013 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Francis Lachapelle <flachapelle@inverse.ca>
|
||||
* Copyright (C) 2006-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
@@ -28,22 +25,22 @@ $plugins
|
||||
= array(
|
||||
"sogo-connector@inverse.ca"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "24.0.4",
|
||||
"filename" => "sogo-connector-24.0.4.xpi" ),
|
||||
"version" => "31.0.0",
|
||||
"filename" => "sogo-connector-31.0.0.xpi" ),
|
||||
"sogo-integrator@inverse.ca"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "24.0.4",
|
||||
"filename" => "sogo-integrator-24.0.4.xpi" ),
|
||||
"version" => "31.0.0",
|
||||
"filename" => "sogo-integrator-31.0.0.xpi" ),
|
||||
"{e2fda1a4-762b-4020-b5ad-a41df1933103}"
|
||||
=> array( "application" => "thunderbird",
|
||||
"version" => "2.6.4",
|
||||
"filename" => "lightning-2.6.4.xpi" )
|
||||
"version" => "3.3.1",
|
||||
"filename" => "lightning-3.3.1.xpi" )
|
||||
);
|
||||
|
||||
$applications
|
||||
= array( "thunderbird" => "<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
|
||||
<em:minVersion>24.0</em:minVersion>
|
||||
<em:maxVersion>24.*</em:maxVersion>" );
|
||||
<em:minVersion>31.0</em:minVersion>
|
||||
<em:maxVersion>31.*</em:maxVersion>" );
|
||||
|
||||
$pluginname = $_GET["plugin"];
|
||||
$plugin =& $plugins[$pluginname];
|
||||
|
||||
@@ -28,23 +28,23 @@ vtodo_class2 = "(Konfidensiell oppgave)";
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Hendelseinvitasjon: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(sendt av %{SentBy})";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.⏎ ⏎ Start: %{StartDate}⏎ Slutt: %{EndDate}⏎ Beskrivelse: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.\n\nStart: %{StartDate}\nSlutt: %{EndDate}\nBeskrivelse: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.\n\nStart: %{StartDate} klokken %{StartTime}\nSlutt: %{EndDate} klokken %{EndTime}\nBeskrivelse: %{Description}";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Hendelse avlyst: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText} har avlyst hendelsen: %{Summary}.⏎ ⏎ Start: %{StartDate}⏎ Slutt: %{EndDate}⏎ Beskrivelse: %{Description}";
|
||||
= "%{Organizer} %{SentByText} har avlyst hendelsen: %{Summary}.\n\nStart: %{StartDate}\nSlutt: %{EndDate}\nBeskrivelse: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText} har avlyst : %{Summary}.\n\nStart: %{StartDate} klokken %{StartTime}\nEnd: %{EndDate} klokken %{EndTime}\nBeskrivelse: %{Description}";
|
||||
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "Avtalen \"%{Summary}\", %{OldStartDate} er endret";
|
||||
= "Avtalen \"%{Summary}\", %{OldStartDate} har endret seg";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "Avtalen \"%{Summary}\" for %{OldStartDate} klokken %{OldStartTime} er endret.";
|
||||
= "Avtalen \"%{Summary}\" for %{OldStartDate} klokken %{OldStartTime} har endret seg";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "Følgende parametre er endret for \"%{Summary}\"-møtet:";
|
||||
= "Følgende parametre har endret seg for \"%{Summary}\" møtet:";
|
||||
"Please accept or decline those changes."
|
||||
= "Vennligst godta eller avvis endringene.";
|
||||
|
||||
@@ -52,16 +52,16 @@ vtodo_class2 = "(Konfidensiell oppgave)";
|
||||
"Accepted invitation: \"%{Summary}\"" = "Aksepterte invitasjonen: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "Avviste invitasjonen: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "Delegerte invitasjonen: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "Fortsatt ikke svart på invitasjonen: \"%{Summary}";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "Har enda ikke svart på invitasjonen: \"%{Summary}";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText} har godtatt invitasjonen.";
|
||||
= "%{Attendee} %{SentByText} har godtatt invitasjonen din.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText} har avvist invitasjonen.";
|
||||
= "%{Attendee} %{SentByText} har avvist invitasjonen din.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText} har delegert invitasjonen til %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText} har ikke svart på invitasjonen.";
|
||||
= "%{Attendee} %{SentByText} har enda ikke svart på invitasjonen din.";
|
||||
|
||||
/* Resources */
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Kan ikke få tilgang til ressurs: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maksimum antall samtidige reservasjoner (%{NumberOfSimultaneousBookings}) er nådd for ressursen \"%{Cn} %{SystemEmail}\". Kolliderende hendelse er \"%{EventTitle}\", som starter %{StartDate}.";
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Har ikke tilgang til ressurs: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maksimum antall samtidige reservasjoner (%{NumberOfSimultaneousBookings}) er nådd for ressursen \"%{Cn} %{SystemEmail}\". Den kolliderende hendelsen er \"%{EventTitle}\", og starter %{StartDate}.";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
"Inviting the following persons is prohibited:" = "Приглашение следующих лиц запрещено:";
|
||||
"Personal Calendar" = "Персональный календарь";
|
||||
vevent_class0 = "(Публичное событие)";
|
||||
vevent_class1 = "(Личное событие)";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
Copyright (C) 2007-2012 Inverse inc.
|
||||
Copyright (C) 2007-2014 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
@class GCSFolder;
|
||||
@class iCalCalendar;
|
||||
@class iCalTimeZone;
|
||||
@class NGCalendarDateRange;
|
||||
@class SOGoWebDAVValue;
|
||||
|
||||
typedef enum {
|
||||
@@ -118,6 +119,11 @@ typedef enum {
|
||||
- (NSArray *) fetchAlarmInfosFrom: (NSNumber *) _startUTCDate
|
||||
to: (NSNumber *) _endUTCDate;
|
||||
|
||||
- (void) flattenCycleRecord: (NSDictionary *) theRecord
|
||||
forRange: (NGCalendarDateRange *) theRange
|
||||
intoArray: (NSMutableArray *) theRecords
|
||||
withCalendar: (iCalCalendar *) calendar;
|
||||
|
||||
/* URL generation */
|
||||
|
||||
- (NSString *) baseURLForAptWithUID: (NSString *) _uid
|
||||
@@ -138,11 +144,6 @@ typedef enum {
|
||||
- (NSArray *) lookupCalendarFoldersForICalPerson: (NSArray *) _persons
|
||||
inContext: (id) _ctx;
|
||||
|
||||
// - (id) lookupGroupFolderForUIDs: (NSArray *) _uids
|
||||
// inContext: (id) _ctx;
|
||||
// - (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids
|
||||
// inContext: (id) _ctx;
|
||||
|
||||
/* bulk fetches */
|
||||
|
||||
- (NSString *) aclSQLListingFilter;
|
||||
@@ -186,6 +187,11 @@ typedef enum {
|
||||
|
||||
- (NSArray *) aclUsersWithProxyWriteAccess: (BOOL) write;
|
||||
|
||||
- (void) findEntityForClosestAlarm: (id *) theEntity
|
||||
timezone: (NSTimeZone *) theTimeZone
|
||||
startDate: (NSCalendarDate **) theStartDate
|
||||
endDate: (NSCalendarDate **) theEndDate;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __Appointments_SOGoAppointmentFolder_H__ */
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#import <DOM/DOMProtocols.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <EOControl/EOSortOrdering.h>
|
||||
#import <NGCards/iCalAlarm.h>
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalFreeBusy.h>
|
||||
@@ -49,6 +50,7 @@
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalTimeZonePeriod.h>
|
||||
#import <NGCards/iCalToDo.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
@@ -74,6 +76,7 @@
|
||||
#import <SOGo/WORequest+SOGo.h>
|
||||
#import <SOGo/WOResponse+SOGo.h>
|
||||
|
||||
#import "iCalCalendar+SOGo.h"
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
#import "iCalEvent+SOGo.h"
|
||||
#import "iCalPerson+SOGo.h"
|
||||
@@ -99,7 +102,7 @@
|
||||
@implementation SOGoAppointmentFolder
|
||||
|
||||
static NSNumber *sharedYes = nil;
|
||||
static iCalEvent *iCalEventK = nil;
|
||||
static Class iCalEventK = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
@@ -769,7 +772,7 @@ static iCalEvent *iCalEventK = nil;
|
||||
* @param theRecord a dictionnary with the attributes of the event.
|
||||
* @return a copy of theRecord with adjusted dates.
|
||||
*/
|
||||
- (NSMutableDictionary *) fixupRecord: (NSDictionary *) theRecord
|
||||
- (NSMutableDictionary *) _fixupRecord: (NSDictionary *) theRecord
|
||||
{
|
||||
NSMutableDictionary *record;
|
||||
static NSString *fields[] = { @"c_startdate", @"startDate",
|
||||
@@ -813,12 +816,12 @@ static iCalEvent *iCalEventK = nil;
|
||||
//
|
||||
//
|
||||
//
|
||||
- (NSArray *) fixupRecords: (NSArray *) theRecords
|
||||
- (NSArray *) _fixupRecords: (NSArray *) theRecords
|
||||
{
|
||||
// TODO: is the result supposed to be sorted by date?
|
||||
NSMutableArray *ma;
|
||||
unsigned count, max;
|
||||
id row; // TODO: what is the type of the record?
|
||||
id row;
|
||||
|
||||
if (theRecords)
|
||||
{
|
||||
@@ -826,7 +829,7 @@ static iCalEvent *iCalEventK = nil;
|
||||
ma = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
row = [self fixupRecord: [theRecords objectAtIndex: count]];
|
||||
row = [self _fixupRecord: [theRecords objectAtIndex: count]];
|
||||
if (row)
|
||||
[ma addObject: row];
|
||||
}
|
||||
@@ -900,6 +903,9 @@ static iCalEvent *iCalEventK = nil;
|
||||
return record;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (int) _indexOfRecordMatchingDate: (NSCalendarDate *) matchDate
|
||||
inArray: (NSArray *) recordArray
|
||||
{
|
||||
@@ -922,6 +928,9 @@ static iCalEvent *iCalEventK = nil;
|
||||
return recordIndex;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _fixExceptionRecord: (NSMutableDictionary *) recRecord
|
||||
fromRow: (NSDictionary *) row
|
||||
{
|
||||
@@ -938,12 +947,57 @@ static iCalEvent *iCalEventK = nil;
|
||||
[recRecord setObjects: objects forKeys: fields];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _computeAlarmForRow: (NSMutableDictionary *) row
|
||||
master: (iCalEntityObject *) master
|
||||
{
|
||||
iCalEntityObject *component;
|
||||
iCalAlarm *alarm;
|
||||
|
||||
if (![master recurrenceId])
|
||||
{
|
||||
component = [master copy];
|
||||
|
||||
[component setStartDate: [NSCalendarDate dateWithTimeIntervalSince1970: [[row objectForKey: @"c_startdate"] intValue]]];
|
||||
|
||||
if ([component isKindOfClass: [iCalEvent class]])
|
||||
{
|
||||
[(iCalEvent *)component setEndDate: [NSCalendarDate dateWithTimeIntervalSince1970: [[row objectForKey: @"c_enddate"] intValue]]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[(iCalToDo *)component setDue: [NSCalendarDate dateWithTimeIntervalSince1970: [[row objectForKey: @"c_enddate"] intValue]]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component = master;
|
||||
RETAIN(component);
|
||||
}
|
||||
|
||||
// Check if we have any alarm, that could happen for recurrence exceptions with no
|
||||
// alarm defined.
|
||||
if ([[component alarms] count])
|
||||
{
|
||||
alarm = [component firstDisplayOrAudioAlarm];
|
||||
[row setObject: [NSNumber numberWithInt: [[alarm nextAlarmDate] timeIntervalSince1970]]
|
||||
forKey: @"c_nextalarm"];
|
||||
}
|
||||
|
||||
RELEASE(component);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _appendCycleException: (iCalRepeatableEntityObject *) component
|
||||
firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
fromRow: (NSDictionary *) row
|
||||
forRange: (NGCalendarDateRange *) dateRange
|
||||
withTimeZone: (NSTimeZone *) tz
|
||||
toArray: (NSMutableArray *) ma
|
||||
withTimeZone: (NSTimeZone *) tz
|
||||
toArray: (NSMutableArray *) ma
|
||||
{
|
||||
NSCalendarDate *recurrenceId;
|
||||
NSMutableDictionary *newRecord;
|
||||
@@ -983,7 +1037,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
{
|
||||
if ([dateRange containsDate: [component startDate]])
|
||||
{
|
||||
newRecord = [self fixupRecord: [component quickRecordForContainer: self]];
|
||||
// We must pass nill to :container here in order to avoid re-entrancy issues.
|
||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
|
||||
}
|
||||
else
|
||||
@@ -998,8 +1053,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
else
|
||||
{
|
||||
// The recurrence id of the exception is outside the date range;
|
||||
// simply add the exception to the records array
|
||||
newRecord = [self fixupRecord: [component quickRecordForContainer: self]];
|
||||
// simply add the exception to the records array.
|
||||
// We must pass nill to :container here in order to avoid re-entrancy issues.
|
||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||
newRecordRange = [NGCalendarDateRange
|
||||
calendarDateRangeWithStartDate: [newRecord objectForKey: @"startDate"]
|
||||
endDate: [newRecord objectForKey: @"endDate"]];
|
||||
@@ -1024,6 +1080,10 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
|
||||
[self _fixExceptionRecord: newRecord fromRow: row];
|
||||
}
|
||||
|
||||
// We finally adjust the c_nextalarm
|
||||
[self _computeAlarmForRow: (id)row
|
||||
master: component];
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1033,30 +1093,32 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
forRange: (NGCalendarDateRange *) dateRange
|
||||
withTimeZone: (NSTimeZone *) tz
|
||||
withCalendar: (iCalCalendar *) calendar
|
||||
toArray: (NSMutableArray *) ma
|
||||
{
|
||||
NSArray *elements, *components;
|
||||
unsigned int count, max;
|
||||
NSArray *components;
|
||||
NSString *content;
|
||||
|
||||
unsigned int count, max;
|
||||
|
||||
content = [row objectForKey: @"c_content"];
|
||||
if ([content length])
|
||||
|
||||
if (!calendar && [content isNotNull])
|
||||
{
|
||||
// TODO : c_content could have already been parsed.
|
||||
// @see _flattenCycleRecord:forRange:intoArray:
|
||||
elements = [iCalCalendar parseFromSource: content];
|
||||
if ([elements count])
|
||||
{
|
||||
components = [[elements objectAtIndex: 0] allObjects];
|
||||
max = [components count];
|
||||
for (count = 1; count < max; count++) // skip master event
|
||||
[self _appendCycleException: [components objectAtIndex: count]
|
||||
firstInstanceCalendarDateRange: fir
|
||||
fromRow: row
|
||||
forRange: dateRange
|
||||
withTimeZone: tz
|
||||
toArray: ma];
|
||||
}
|
||||
calendar = [iCalCalendar parseSingleFromSource: content];
|
||||
}
|
||||
|
||||
if (calendar)
|
||||
{
|
||||
components = [calendar allObjects];
|
||||
max = [components count];
|
||||
for (count = 1; count < max; count++) // skip master event
|
||||
[self _appendCycleException: [components objectAtIndex: count]
|
||||
firstInstanceCalendarDateRange: fir
|
||||
fromRow: row
|
||||
forRange: dateRange
|
||||
withTimeZone: tz
|
||||
toArray: ma];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1068,21 +1130,23 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
* @param theRecords the array into which are copied the resulting occurrences.
|
||||
* @see [iCalRepeatableEntityObject+SOGo doesOccurOnDate:]
|
||||
*/
|
||||
- (void) _flattenCycleRecord: (NSDictionary *) theRecord
|
||||
forRange: (NGCalendarDateRange *) theRange
|
||||
intoArray: (NSMutableArray *) theRecords
|
||||
- (void) flattenCycleRecord: (NSDictionary *) theRecord
|
||||
forRange: (NGCalendarDateRange *) theRange
|
||||
intoArray: (NSMutableArray *) theRecords
|
||||
withCalendar: (iCalCalendar *) calendar
|
||||
|
||||
{
|
||||
NSMutableDictionary *row, *fixedRow;
|
||||
NSMutableArray *records;
|
||||
NSDictionary *cycleinfo;
|
||||
NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange;
|
||||
NSArray *rules, *exRules, *exDates, *ranges;
|
||||
NSArray *elements, *components;
|
||||
NSArray *components;
|
||||
NSString *content;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate, *firstEndDate;
|
||||
NSTimeZone *allDayTimeZone;
|
||||
iCalDateTime *dtstart;
|
||||
iCalEvent *component;
|
||||
iCalRepeatableEntityObject *component;
|
||||
iCalTimeZone *eventTimeZone;
|
||||
unsigned count, max, offset;
|
||||
id tz;
|
||||
@@ -1109,104 +1173,122 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
allDayTimeZone = nil;
|
||||
tz = nil;
|
||||
|
||||
row = [self fixupRecord: theRecord];
|
||||
row = [self _fixupRecord: theRecord];
|
||||
[row removeObjectForKey: @"c_cycleinfo"];
|
||||
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
||||
|
||||
content = [theRecord objectForKey: @"c_content"];
|
||||
if ([content isNotNull])
|
||||
|
||||
if (!calendar && [content isNotNull])
|
||||
{
|
||||
elements = [iCalCalendar parseFromSource: content];
|
||||
if ([elements count])
|
||||
{
|
||||
components = [[elements objectAtIndex: 0] events];
|
||||
if ([components count])
|
||||
{
|
||||
// Retrieve the range of the first/master event
|
||||
component = [components objectAtIndex: 0];
|
||||
dtstart = (iCalDateTime *) [component uniqueChildWithTag: @"dtstart"];
|
||||
firstRange = [component firstOccurenceRange]; // ignores timezone
|
||||
calendar = [iCalCalendar parseSingleFromSource: content];
|
||||
}
|
||||
|
||||
eventTimeZone = [dtstart timeZone];
|
||||
if (eventTimeZone)
|
||||
{
|
||||
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
endDate: checkEndDate];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
recurrenceRange = theRange;
|
||||
if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
allDayTimeZone = timeZone;
|
||||
offset = [allDayTimeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[firstStartDate setTimeZone: allDayTimeZone];
|
||||
[firstEndDate setTimeZone: allDayTimeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
#warning this code is ugly: we should not mix objects with different types as\
|
||||
it reduces readability
|
||||
tz = eventTimeZone ? eventTimeZone : allDayTimeZone;
|
||||
if (tz)
|
||||
{
|
||||
// Adjust the exception dates
|
||||
exDates = [component exceptionDatesWithTimeZone: tz];
|
||||
|
||||
// Adjust the recurrence rules "until" dates
|
||||
rules = [component recurrenceRulesWithTimeZone: tz];
|
||||
exRules = [component exceptionRulesWithTimeZone: tz];
|
||||
}
|
||||
|
||||
// Calculate the occurrences for the given range
|
||||
records = [NSMutableArray array];
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
recurrenceRules: rules
|
||||
exceptionRules: exRules
|
||||
exceptionDates: exDates];
|
||||
max = [ranges count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
oneRange = [ranges objectAtIndex: count];
|
||||
fixedRow = [self fixupCycleRecord: row
|
||||
cycleRange: oneRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
withEventTimeZone: eventTimeZone];
|
||||
if (fixedRow)
|
||||
[records addObject: fixedRow];
|
||||
}
|
||||
if (calendar)
|
||||
{
|
||||
if ([[theRecord objectForKey: @"c_component"] isEqualToString: @"vtodo"])
|
||||
components = [calendar todos];
|
||||
else
|
||||
components = [calendar events];
|
||||
|
||||
if ([components count])
|
||||
{
|
||||
// Retrieve the range of the first/master event
|
||||
component = [components objectAtIndex: 0];
|
||||
dtstart = (iCalDateTime *) [component uniqueChildWithTag: @"dtstart"];
|
||||
firstRange = [component firstOccurenceRange]; // ignores timezone
|
||||
|
||||
eventTimeZone = [dtstart timeZone];
|
||||
if (eventTimeZone)
|
||||
{
|
||||
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
endDate: checkEndDate];
|
||||
|
||||
[self _appendCycleExceptionsFromRow: row
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
forRange: theRange
|
||||
withTimeZone: allDayTimeZone
|
||||
toArray: records];
|
||||
|
||||
[theRecords addObjectsFromArray: records];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
recurrenceRange = theRange;
|
||||
if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
allDayTimeZone = timeZone;
|
||||
offset = [allDayTimeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[firstStartDate setTimeZone: allDayTimeZone];
|
||||
[firstEndDate setTimeZone: allDayTimeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
#warning this code is ugly: we should not mix objects with different types as \
|
||||
it reduces readability
|
||||
tz = eventTimeZone ? eventTimeZone : allDayTimeZone;
|
||||
if (tz)
|
||||
{
|
||||
// Adjust the exception dates
|
||||
exDates = [component exceptionDatesWithTimeZone: tz];
|
||||
|
||||
// Adjust the recurrence rules "until" dates
|
||||
rules = [component recurrenceRulesWithTimeZone: tz];
|
||||
exRules = [component exceptionRulesWithTimeZone: tz];
|
||||
}
|
||||
|
||||
// Calculate the occurrences for the given range
|
||||
records = [NSMutableArray array];
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
recurrenceRules: rules
|
||||
exceptionRules: exRules
|
||||
exceptionDates: exDates];
|
||||
max = [ranges count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
oneRange = [ranges objectAtIndex: count];
|
||||
fixedRow = [self fixupCycleRecord: row
|
||||
cycleRange: oneRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
withEventTimeZone: eventTimeZone];
|
||||
|
||||
// We now adjust the c_nextalarm based on each occurences. For each of them, we use the master event
|
||||
// alarm information since exceptions to recurrence rules might have their own, while that is not the
|
||||
// case for standard occurences.
|
||||
if ([component hasAlarms])
|
||||
{
|
||||
[self _computeAlarmForRow: fixedRow
|
||||
master: component];
|
||||
}
|
||||
|
||||
[records addObject: fixedRow];
|
||||
}
|
||||
|
||||
[self _appendCycleExceptionsFromRow: row
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
forRange: theRange
|
||||
withTimeZone: allDayTimeZone
|
||||
withCalendar: calendar
|
||||
toArray: records];
|
||||
|
||||
[theRecords addObjectsFromArray: records];
|
||||
} // if ([components count]) ...
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:@"cyclic record doesn't have content -> %@", theRecord];
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: is the result supposed to be sorted by date?
|
||||
//
|
||||
- (NSArray *) _flattenCycleRecords: (NSArray *) _records
|
||||
fetchRange: (NGCalendarDateRange *) _r
|
||||
{
|
||||
// TODO: is the result supposed to be sorted by date?
|
||||
NSMutableArray *ma;
|
||||
NSDictionary *row;
|
||||
NSCalendarDate *rangeEndDate;
|
||||
@@ -1224,12 +1306,15 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
row = [_records objectAtIndex: count];
|
||||
[self _flattenCycleRecord: row forRange: _r intoArray: ma];
|
||||
[self flattenCycleRecord: row forRange: _r intoArray: ma withCalendar: nil];
|
||||
}
|
||||
|
||||
return ma;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _buildStripFieldsFromFields: (NSArray *) fields
|
||||
{
|
||||
stripFields = [[NSMutableArray alloc] initWithCapacity: [fields count]];
|
||||
@@ -1246,6 +1331,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
@"c_component", nil]];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _fixupProtectedInformation: (NSEnumerator *) ma
|
||||
inFields: (NSArray *) fields
|
||||
forUser: (NSString *) uid
|
||||
@@ -1299,7 +1387,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
BOOL rememberRecords, canCycle;
|
||||
|
||||
rememberRecords = [self _checkIfWeCanRememberRecords: _fields];
|
||||
canCycle = [_component isEqualToString: @"vevent"];
|
||||
canCycle = [_component isEqualToString: @"vevent"] || [_component isEqualToString: @"vtodo"];
|
||||
// if (rememberRecords)
|
||||
// NSLog (@"we will remember those records!");
|
||||
|
||||
@@ -1341,28 +1429,31 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
}
|
||||
|
||||
privacySQLString = [self aclSQLListingFilter];
|
||||
|
||||
if (privacySQLString)
|
||||
{
|
||||
if ([privacySQLString length])
|
||||
[baseWhere addObject: privacySQLString];
|
||||
|
||||
|
||||
if ([title length])
|
||||
if ([filters length])
|
||||
{
|
||||
if ([filters isEqualToString:@"title_Category_Location"] || [filters isEqualToString:@"entireContent"])
|
||||
{
|
||||
[baseWhere addObject: [NSString stringWithFormat: @"(c_title isCaseInsensitiveLike: '%%%@%%' OR c_category isCaseInsensitiveLike: '%%%@%%' OR c_location isCaseInsensitiveLike: '%%%@%%')",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"],
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"],
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]]];
|
||||
}
|
||||
if ([filters length])
|
||||
{
|
||||
if ([filters isEqualToString:@"title_Category_Location"] || [filters isEqualToString:@"entireContent"])
|
||||
{
|
||||
[baseWhere addObject: [NSString stringWithFormat: @"(c_title isCaseInsensitiveLike: '%%%@%%' OR c_category isCaseInsensitiveLike: '%%%@%%' OR c_location isCaseInsensitiveLike: '%%%@%%')",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"],
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"],
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]]];
|
||||
}
|
||||
}
|
||||
else
|
||||
[baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]]];
|
||||
}
|
||||
else
|
||||
[baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]]];
|
||||
|
||||
|
||||
/* prepare mandatory fields */
|
||||
|
||||
|
||||
fields = [NSMutableArray arrayWithArray: _fields];
|
||||
[fields addObjectUniquely: @"c_name"];
|
||||
[fields addObjectUniquely: @"c_uid"];
|
||||
@@ -1386,7 +1477,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
if (records)
|
||||
{
|
||||
if (r)
|
||||
records = [self fixupRecords: records];
|
||||
records = [self _fixupRecords: records];
|
||||
ma = [NSMutableArray arrayWithArray: records];
|
||||
}
|
||||
else
|
||||
@@ -1585,6 +1676,32 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
NSCalendarDate *maxStart;
|
||||
|
||||
parentNode = (id <DOMElement>) [filterElement parentNode];
|
||||
|
||||
// This parses time-range filters.
|
||||
//
|
||||
// <C:filter>
|
||||
// <C:comp-filter name="VCALENDAR">
|
||||
// <C:comp-filter name="VEVENT">
|
||||
// <C:time-range start="20060104T000000Z"
|
||||
// end="20060105T000000Z"/>
|
||||
// </C:comp-filter>
|
||||
// </C:comp-filter>
|
||||
// </C:filter>
|
||||
//
|
||||
//
|
||||
// We currently ignore filters based on just the component type.
|
||||
// For example, this is ignored:
|
||||
//
|
||||
// <c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
// <d:prop>
|
||||
// <d:getetag />
|
||||
// <c:calendar-data />
|
||||
// </d:prop>
|
||||
// <c:filter>
|
||||
// <c:comp-filter name="VCALENDAR" />
|
||||
// </c:filter>
|
||||
// </c:calendar-query>
|
||||
//
|
||||
if ([[parentNode tagName] isEqualToString: @"comp-filter"]
|
||||
&& [[parentNode attribute: @"name"] isEqualToString: @"VCALENDAR"])
|
||||
{
|
||||
@@ -1971,26 +2088,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
return [name isEqualToString: @"OPTIONS"];
|
||||
}
|
||||
|
||||
/*
|
||||
- (id) lookupComponentByUID: (NSString *) uid
|
||||
{
|
||||
NSString *filename;
|
||||
id component;
|
||||
|
||||
filename = [self resourceNameForEventUID: uid];
|
||||
if (filename)
|
||||
{
|
||||
component = [self lookupName: filename inContext: context acquire: NO];
|
||||
if ([component isKindOfClass: [NSException class]])
|
||||
component = nil;
|
||||
}
|
||||
else
|
||||
component = nil;
|
||||
|
||||
return nil;
|
||||
}
|
||||
*/
|
||||
|
||||
- (id) lookupName: (NSString *)_key
|
||||
inContext: (id)_ctx
|
||||
acquire: (BOOL)_flag
|
||||
@@ -2297,6 +2394,12 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
[components addObject: [SOGoWebDAVValue
|
||||
valueForObject: @"<n1:comp name=\"VEVENT\"/>"
|
||||
attributes: nil]];
|
||||
|
||||
// See bugs #2878 and #2879
|
||||
[components addObject: [SOGoWebDAVValue
|
||||
valueForObject: @"<n1:comp name=\"VFREEBUSY\"/>"
|
||||
attributes: nil]];
|
||||
|
||||
if ([self showCalendarTasks])
|
||||
[components addObject: [SOGoWebDAVValue
|
||||
valueForObject: @"<n1:comp name=\"VTODO\"/>"
|
||||
@@ -3356,5 +3459,127 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
return activeTasks;
|
||||
}
|
||||
|
||||
- (void) findEntityForClosestAlarm: (id *) theEntity
|
||||
timezone: (NSTimeZone *) theTimeZone
|
||||
startDate: (NSCalendarDate **) theStartDate
|
||||
endDate: (NSCalendarDate **) theEndDate
|
||||
{
|
||||
// If the event is recurring, we MUST find the right occurence.
|
||||
if ([*theEntity hasRecurrenceRules])
|
||||
{
|
||||
NSCalendarDate *startDate, *endDate;
|
||||
NSMutableDictionary *quickRecord;
|
||||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *range;
|
||||
NSMutableArray *alarms;
|
||||
iCalDateTime *date;
|
||||
iCalTimeZone *tz;
|
||||
|
||||
BOOL b, isEvent;
|
||||
|
||||
isEvent = [*theEntity isKindOfClass: [iCalEvent class]];
|
||||
b = NO;
|
||||
|
||||
if (isEvent)
|
||||
b = [*theEntity isAllDay];
|
||||
|
||||
// We build a fake "quick record". Our record must include some mandatory info, like @"c_startdate" and @"c_enddate"
|
||||
quickRecord = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: b], @"c_isallday",
|
||||
[NSNumber numberWithBool: [*theEntity isRecurrent]], @"c_iscycle",
|
||||
nil];
|
||||
startDate = [*theEntity startDate];
|
||||
endDate = (isEvent ? [*theEntity endDate] : [*theEntity due]);
|
||||
|
||||
if ([startDate isNotNull])
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
// An all-day event usually doesn't have a timezone associated to its
|
||||
// start date; however, if it does, we convert it to GMT.
|
||||
date = (iCalDateTime*) [*theEntity uniqueChildWithTag: @"dtstart"];
|
||||
tz = [(iCalDateTime*) date timeZone];
|
||||
if (tz)
|
||||
startDate = [tz computedDateForDate: startDate];
|
||||
}
|
||||
[quickRecord setObject: [*theEntity quickRecordDateAsNumber: startDate
|
||||
withOffset: 0
|
||||
forAllDay: b]
|
||||
forKey: @"c_startdate"];
|
||||
}
|
||||
|
||||
if ([endDate isNotNull])
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
// An all-day event usually doesn't have a timezone associated to its
|
||||
// end date; however, if it does, we convert it to GMT.
|
||||
date = (isEvent ? (iCalDateTime*) [*theEntity uniqueChildWithTag: @"dtend"] : (iCalDateTime*) [*theEntity uniqueChildWithTag: @"due"]);
|
||||
tz = [(iCalDateTime*) date timeZone];
|
||||
if (tz)
|
||||
endDate = [tz computedDateForDate: endDate];
|
||||
}
|
||||
[quickRecord setObject: [*theEntity quickRecordDateAsNumber: endDate
|
||||
withOffset: ((b) ? -1 : 0)
|
||||
forAllDay: b]
|
||||
forKey: @"c_enddate"];
|
||||
}
|
||||
|
||||
|
||||
if ([*theEntity isRecurrent])
|
||||
{
|
||||
NSCalendarDate *date;
|
||||
|
||||
date = [*theEntity lastPossibleRecurrenceStartDate];
|
||||
if (!date)
|
||||
{
|
||||
/* this could also be *nil*, but in the end it makes the fetchspecs
|
||||
more complex - thus we set it to a "reasonable" distant future */
|
||||
date = iCalDistantFuture;
|
||||
}
|
||||
[quickRecord setObject: [*theEntity quickRecordDateAsNumber: date
|
||||
withOffset: 0 forAllDay: NO]
|
||||
forKey: @"c_cycleenddate"];
|
||||
[quickRecord setObject: [*theEntity cycleInfo] forKey: @"c_cycleinfo"];
|
||||
}
|
||||
|
||||
alarms = [NSMutableArray array];
|
||||
start = [NSCalendarDate date];
|
||||
end = [start addYear:1 month:0 day:0 hour:0 minute:0 second:0];
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
|
||||
[self flattenCycleRecord: quickRecord
|
||||
forRange: range
|
||||
intoArray: alarms
|
||||
withCalendar: [*theEntity parent]];
|
||||
|
||||
if ([alarms count])
|
||||
{
|
||||
NSDictionary *anAlarm;
|
||||
id o;
|
||||
|
||||
// Take the first alarm since it's the 'closest' one
|
||||
anAlarm = [alarms objectAtIndex: 0];
|
||||
|
||||
// We grab the last one and we use that info. The logic is simple.
|
||||
// 1. grab the RECURRENCE-ID, if found in our master event, use that
|
||||
// 2. if not found, use the master's event info but adjust the start/end date
|
||||
if ((o = [[*theEntity parent] eventWithRecurrenceID: [anAlarm objectForKey: @"c_recurrence_id"]]))
|
||||
{
|
||||
*theEntity = o;
|
||||
*theStartDate = [*theEntity startDate];
|
||||
*theEndDate = [*theEntity endDate];
|
||||
}
|
||||
else
|
||||
{
|
||||
*theStartDate = [NSCalendarDate dateWithTimeIntervalSince1970: [[anAlarm objectForKey: @"c_startdate"] intValue]];
|
||||
*theEndDate = [NSCalendarDate dateWithTimeIntervalSince1970: [[anAlarm objectForKey: @"c_enddate"] intValue]];
|
||||
}
|
||||
|
||||
[*theStartDate setTimeZone: theTimeZone];
|
||||
[*theEndDate setTimeZone: theTimeZone];
|
||||
}
|
||||
} // if ([event hasRecurrenceRules]) ...
|
||||
}
|
||||
|
||||
@end /* SOGoAppointmentFolder */
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
|
||||
#import <DOM/DOMElement.h>
|
||||
#import <DOM/DOMNode.h>
|
||||
#import <DOM/DOMProtocols.h>
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
@@ -58,6 +60,40 @@
|
||||
|
||||
static SoSecurityManager *sm = nil;
|
||||
|
||||
@interface NGDOMElement (SOGo)
|
||||
|
||||
- (BOOL) isTextNode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NGDOMElement (SOGo)
|
||||
|
||||
- (BOOL) isTextNode
|
||||
{
|
||||
id <DOMNodeList> children;
|
||||
id <DOMElement> element;
|
||||
int i;
|
||||
|
||||
if ([self nodeType] == DOM_TEXT_NODE)
|
||||
return YES;
|
||||
|
||||
children = [self childNodes];
|
||||
|
||||
for (i = 0; i < [children length]; i++)
|
||||
{
|
||||
element = [children objectAtIndex: i];
|
||||
|
||||
if ([element nodeType] != DOM_TEXT_NODE)
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation SOGoAppointmentFolders
|
||||
|
||||
+ (void) initialize
|
||||
@@ -307,10 +343,17 @@ static SoSecurityManager *sm = nil;
|
||||
[currentElement nodeName]];
|
||||
if ([currentName isEqualToString: propertyName])
|
||||
{
|
||||
values = [currentElement childNodes];
|
||||
if ([values length])
|
||||
property = [[values objectAtIndex: 0] nodeValue];
|
||||
}
|
||||
if ([(id)currentElement isTextNode])
|
||||
{
|
||||
property = [(id)currentElement textValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
values = [currentElement childNodes];
|
||||
if ([values length])
|
||||
property = [[values objectAtIndex: 0] nodeValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return property;
|
||||
@@ -333,7 +376,11 @@ static SoSecurityManager *sm = nil;
|
||||
values = [currentProperty childNodes];
|
||||
if ([values length])
|
||||
{
|
||||
value = [[values objectAtIndex: 0] nodeValue];
|
||||
if ([(id)currentProperty isTextNode])
|
||||
value = [(id)currentProperty textValue];
|
||||
else
|
||||
value = [[values objectAtIndex: 0] nodeValue];
|
||||
|
||||
currentName = [NSString stringWithFormat: @"{%@}%@",
|
||||
[currentProperty namespaceURI],
|
||||
[currentProperty nodeName]];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2007-2013 Inverse inc.
|
||||
Copyright (C) 2007-2014 Inverse inc.
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo
|
||||
@@ -42,6 +42,9 @@
|
||||
#import <NGCards/NSCalendarDate+NGCards.h>
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalTimeZonePeriod.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
|
||||
#import <SOGo/SOGoConstants.h>
|
||||
@@ -49,6 +52,7 @@
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSObject+DAV.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoObject.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoGroup.h>
|
||||
@@ -160,7 +164,7 @@
|
||||
object = nil;
|
||||
}
|
||||
else
|
||||
object = nil;
|
||||
object = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +185,8 @@
|
||||
//
|
||||
//
|
||||
- (void) _addOrUpdateEvent: (iCalEvent *) theEvent
|
||||
forUID: (NSString *) theUID
|
||||
owner: (NSString *) theOwner
|
||||
forUID: (NSString *) theUID
|
||||
owner: (NSString *) theOwner
|
||||
{
|
||||
if (![theUID isEqualToString: theOwner])
|
||||
{
|
||||
@@ -432,17 +436,20 @@
|
||||
while ((currentAttendee = [enumerator nextObject]))
|
||||
{
|
||||
currentUID = [currentAttendee uid];
|
||||
|
||||
if (currentUID)
|
||||
{
|
||||
user = [SOGoUser userWithLogin: currentUID];
|
||||
us = [user userSettings];
|
||||
moduleSettings = [us objectForKey:@"Calendar"];
|
||||
|
||||
// Check if the user prevented his account from beeing invited to events
|
||||
if (![user isResource] && [[moduleSettings objectForKey:@"PreventInvitations"] boolValue])
|
||||
{
|
||||
// Check if the user have a whiteList
|
||||
whiteListString = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
|
||||
whiteList = [whiteListString objectFromJSONString];
|
||||
|
||||
// If the filter have a hit, do not add the currentUID to the unavailableAttendees array
|
||||
if (![whiteList objectForKey:ownerUID])
|
||||
{
|
||||
@@ -454,9 +461,11 @@
|
||||
}
|
||||
|
||||
count = [unavailableAttendees count];
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
reason = [NSMutableString stringWithString:[self labelForKey: @"Inviting the following persons is prohibited:"]];
|
||||
|
||||
// Add all the unavailable users in the warning message
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
@@ -465,10 +474,14 @@
|
||||
if (i < count-2)
|
||||
[reason appendString:@", "];
|
||||
}
|
||||
|
||||
[unavailableAttendees release];
|
||||
|
||||
return [NSException exceptionWithHTTPStatus:409 reason: reason];
|
||||
}
|
||||
|
||||
[unavailableAttendees release];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -523,14 +536,14 @@
|
||||
|
||||
if ([user isResource])
|
||||
{
|
||||
NSCalendarDate *start, *end, *rangeStartDate, *rangeEndDate;
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *range;
|
||||
NSMutableArray *fbInfo;
|
||||
NSArray *allOccurences;
|
||||
|
||||
BOOL must_delete;
|
||||
int i, j;
|
||||
int i, j, delta;
|
||||
|
||||
// We get the start/end date for our conflict range. If the event to be added is recurring, we
|
||||
// check for at least a year to start with.
|
||||
@@ -573,8 +586,18 @@
|
||||
|
||||
for (i = [fbInfo count]-1; i >= 0; i--)
|
||||
{
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: [[fbInfo objectAtIndex: i] objectForKey: @"startDate"]
|
||||
endDate: [[fbInfo objectAtIndex: i] objectForKey: @"endDate"]];
|
||||
// We MUST use the -uniqueChildWithTag method here because the event has been flattened, so its timezone has been
|
||||
// modified in SOGoAppointmentFolder: -fixupCycleRecord: ....
|
||||
rangeStartDate = [[fbInfo objectAtIndex: i] objectForKey: @"startDate"];
|
||||
delta = [[rangeStartDate timeZoneDetail] timeZoneSecondsFromGMT] - [[[(iCalDateTime *)[theEvent uniqueChildWithTag: @"dtstart"] timeZone] periodForDate: [theEvent startDate]] secondsOffsetFromGMT];
|
||||
rangeStartDate = [rangeStartDate dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: delta];
|
||||
|
||||
rangeEndDate = [[fbInfo objectAtIndex: i] objectForKey: @"endDate"];
|
||||
delta = [[rangeEndDate timeZoneDetail] timeZoneSecondsFromGMT] - [[[(iCalDateTime *)[theEvent uniqueChildWithTag: @"dtend"] timeZone] periodForDate: [theEvent endDate]] secondsOffsetFromGMT];
|
||||
rangeEndDate = [rangeEndDate dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: delta];
|
||||
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: rangeStartDate
|
||||
endDate: rangeEndDate];
|
||||
|
||||
if ([[[fbInfo objectAtIndex: i] objectForKey: @"c_uid"] compare: [theEvent uid]] == NSOrderedSame)
|
||||
{
|
||||
@@ -607,9 +630,9 @@
|
||||
{
|
||||
currentAttendee = [theAttendees objectAtIndex: i];
|
||||
if ([[currentAttendee uid] isEqualToString: currentUID])
|
||||
break;
|
||||
break;
|
||||
else
|
||||
currentAttendee = nil;
|
||||
currentAttendee = nil;
|
||||
}
|
||||
|
||||
if ([fbInfo count])
|
||||
@@ -905,7 +928,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
updatedAttendees: nil
|
||||
operation: EventCreated];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
BOOL hasOrganizer;
|
||||
|
||||
@@ -955,10 +978,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
- (NSException *) _updateAttendee: (iCalPerson *) attendee
|
||||
withDelegate: (iCalPerson *) delegate
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
forEventUID: (NSString *) eventUID
|
||||
withRecurrenceId: (NSCalendarDate *) recurrenceId
|
||||
withSequence: (NSNumber *) sequence
|
||||
forUID: (NSString *) uid
|
||||
forEventUID: (NSString *) eventUID
|
||||
withRecurrenceId: (NSCalendarDate *) recurrenceId
|
||||
withSequence: (NSNumber *) sequence
|
||||
forUID: (NSString *) uid
|
||||
shouldAddSentBy: (BOOL) b
|
||||
{
|
||||
SOGoAppointmentObject *eventObject;
|
||||
@@ -1021,12 +1044,12 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
}
|
||||
}
|
||||
else
|
||||
addDelegate = YES;
|
||||
addDelegate = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (otherDelegate)
|
||||
removeDelegate = YES;
|
||||
removeDelegate = YES;
|
||||
}
|
||||
|
||||
if (removeDelegate)
|
||||
@@ -1093,8 +1116,8 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
- (NSException *) _handleAttendee: (iCalPerson *) attendee
|
||||
withDelegate: (iCalPerson *) delegate
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
statusChange: (NSString *) newStatus
|
||||
inEvent: (iCalEvent *) event
|
||||
statusChange: (NSString *) newStatus
|
||||
inEvent: (iCalEvent *) event
|
||||
{
|
||||
NSString *currentStatus, *organizerUID;
|
||||
SOGoUser *ownerUser, *currentUser;
|
||||
@@ -1668,9 +1691,83 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _adjustClassificationInRequestCalendar: (iCalCalendar *) rqCalendar
|
||||
{
|
||||
SOGoUserDefaults *userDefaults;
|
||||
NSString *accessClass;
|
||||
NSArray *allObjects;
|
||||
id entity;
|
||||
|
||||
int i;
|
||||
|
||||
userDefaults = [[context activeUser] userDefaults];
|
||||
allObjects = [rqCalendar allObjects];
|
||||
|
||||
for (i = 0; i < [allObjects count]; i++)
|
||||
{
|
||||
entity = [allObjects objectAtIndex: i];
|
||||
|
||||
if ([entity respondsToSelector: @selector(accessClass)])
|
||||
{
|
||||
accessClass = [entity accessClass];
|
||||
|
||||
if (!accessClass || [accessClass length] == 0)
|
||||
{
|
||||
if ([entity isKindOfClass: [iCalEvent class]])
|
||||
[entity setAccessClass: [userDefaults calendarEventsDefaultClassification]];
|
||||
else if ([entity isKindOfClass: [iCalToDo class]])
|
||||
[entity setAccessClass: [userDefaults calendarTasksDefaultClassification]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// iOS devices (and potentially others) send event invitations with no PARTSTAT defined.
|
||||
// This confuses DAV clients like Thunderbird, or event SOGo web. The RFC says:
|
||||
//
|
||||
// Description: This parameter can be specified on properties with a
|
||||
// CAL-ADDRESS value type. The parameter identifies the participation
|
||||
// status for the calendar user specified by the property value. The
|
||||
// parameter values differ depending on whether they are associated with
|
||||
// a group scheduled "VEVENT", "VTODO" or "VJOURNAL". The values MUST
|
||||
// match one of the values allowed for the given calendar component. If
|
||||
// not specified on a property that allows this parameter, the default
|
||||
// value is NEEDS-ACTION.
|
||||
//
|
||||
- (void) _adjustPartStatInRequestCalendar: (iCalCalendar *) rqCalendar
|
||||
{
|
||||
NSArray *allObjects, *allAttendees;
|
||||
iCalPerson *attendee;
|
||||
id entity;
|
||||
|
||||
int i, j;
|
||||
|
||||
allObjects = [rqCalendar allObjects];
|
||||
|
||||
for (i = 0; i < [allObjects count]; i++)
|
||||
{
|
||||
entity = [allObjects objectAtIndex: i];
|
||||
|
||||
if ([entity isKindOfClass: [iCalEvent class]])
|
||||
{
|
||||
allAttendees = [entity attendees];
|
||||
|
||||
for (j = 0; j < [allAttendees count]; j++)
|
||||
{
|
||||
attendee = [allAttendees objectAtIndex: j];
|
||||
|
||||
if (![[attendee partStat] length])
|
||||
[attendee setPartStat: @"NEEDS-ACTION"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify vCalendar for any inconsistency or missing attributes.
|
||||
* Currently only check if the events have an end date or a duration.
|
||||
* We also check for the default transparency parameters.
|
||||
* @param rq the HTTP PUT request
|
||||
*/
|
||||
- (void) _adjustEventsInRequestCalendar: (iCalCalendar *) rqCalendar
|
||||
@@ -1694,6 +1791,8 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
[event setDuration: @"PT1H"];
|
||||
[self warnWithFormat: @"Invalid event: no end date; setting duration to %@", [event duration]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1816,6 +1915,8 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
}
|
||||
|
||||
[self _adjustEventsInRequestCalendar: calendar];
|
||||
[self _adjustClassificationInRequestCalendar: calendar];
|
||||
[self _adjustPartStatInRequestCalendar: calendar];
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2111,10 +2212,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
WORequest *rq;
|
||||
WOResponse *response;
|
||||
iCalCalendar *rqCalendar;
|
||||
|
||||
|
||||
rq = [_ctx request];
|
||||
rqCalendar = [iCalCalendar parseSingleFromSource: [rq contentAsString]];
|
||||
|
||||
|
||||
if (![self isNew])
|
||||
{
|
||||
//
|
||||
@@ -2126,10 +2227,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
if (ex)
|
||||
return ex;
|
||||
}
|
||||
|
||||
ex = [self updateContentWithCalendar: rqCalendar fromRequest: rq];
|
||||
if (ex)
|
||||
response = (WOResponse *) ex;
|
||||
|
||||
ex = [self updateContentWithCalendar: rqCalendar fromRequest: rq];
|
||||
if (ex)
|
||||
response = (WOResponse *) ex;
|
||||
else
|
||||
{
|
||||
response = [_ctx response];
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoAppointmentOccurence.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2008-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoAppointmentOccurence.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2008-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoComponentOccurence.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2008-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
@@ -56,6 +54,7 @@
|
||||
inContainer: (SOGoCalendarComponent *) newContainer;
|
||||
|
||||
- (void) setComponent: (iCalRepeatableEntityObject *) newComponent;
|
||||
- (iCalRepeatableEntityObject *) masterComponent;
|
||||
- (void) setMasterComponent: (iCalRepeatableEntityObject *) newMaster;
|
||||
|
||||
@end
|
||||
|
||||
@@ -127,6 +127,12 @@
|
||||
ASSIGN (parentCalendar, [component parent]);
|
||||
}
|
||||
|
||||
|
||||
- (iCalRepeatableEntityObject *) masterComponent
|
||||
{
|
||||
return master;
|
||||
}
|
||||
|
||||
- (void) setMasterComponent: (iCalRepeatableEntityObject *) newMaster
|
||||
{
|
||||
master = newMaster;
|
||||
@@ -194,7 +200,7 @@
|
||||
[master increaseSequence];
|
||||
|
||||
// We save the updated iCalendar in the database.
|
||||
error = [container saveComponent: calendar];
|
||||
error = [container saveCalendar: calendar];
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoEMailAlarmsManager.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2010-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoEMailAlarmsManager.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2010-2014 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
||||