Merge to 2.2.9

This commit is contained in:
Ludovic Marcotte
2014-09-26 14:32:47 -04:00
183 changed files with 7297 additions and 938 deletions
+2
View File
@@ -14,3 +14,5 @@ SoObjects/SOGo/derived_src/
Tests/*/config.py
*.pyc
._*
Documentation/*.docbook
Documentation/*.pdf
+16 -3
View File
@@ -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;
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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]];
}
+532
View File
@@ -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
+8
View File
@@ -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
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -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%&amp;version=%ITEM_VERSION%&amp;platform=%PLATFORM%">
by:
<Seq about="http://inverse.ca/sogo-integrator/extensions" isi:updateURL="https://sogo.acme.com/plugins/updates.php?plugin=%ITEM_ID%&amp;version=%ITEM_VERSION%&amp;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[]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 KiB

+16
View File
@@ -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">&#x220f;</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: -->
+175
View File
@@ -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">&#x25aa;</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>
+208
View File
@@ -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 &gt; 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 &gt; 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>
+24
View File
@@ -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>
+32
View File
@@ -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>
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
+41
View File
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

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:
+19
View File
@@ -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:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

+25
View File
@@ -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)
------------------
+1 -1
View File
@@ -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 -3
View File
@@ -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
+1 -1
View File
@@ -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"];
+2 -4
View File
@@ -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 -3
View File
@@ -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
+3 -5
View File
@@ -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;
-2
View File
@@ -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 -5
View File
@@ -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 -3
View File
@@ -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
+15
View File
@@ -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 */
+9 -12
View File
@@ -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 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 = "(Личное событие)";
+12 -6
View File
@@ -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__ */
+377 -152
View File
@@ -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]];
+126 -25
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More